506 prev next chunks index CyanogenMod/android_packages_apps_Trebuchet_29923f5082093b6211894f49edc653c29b28d99b_src/com/android/launcher3/Launcher.java {strict: [[b], [b]], subset: [[b], [b]]}
line based (standard git) jfstmerge spork
   1                                                                                                          
   2 /*                                                                                                       
   3  * Copyright (C) 2008 The Android Open Source Project                                                    
   4  *                                                                                                       
   5  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   6  * you may not use this file except in compliance with the License.                                      
   7  * You may obtain a copy of the License at                                                               
   8  *                                                                                                       
   9  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
  10  *                                                                                                       
  11  * Unless required by applicable law or agreed to in writing, software                                   
  12  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  14  * See the License for the specific language governing permissions and                                   
  15  * limitations under the License.                                                                        
  16  */                                                                                                      
  17                                                                                                          
  18 package com.android.launcher3;                                                                           
  19                                                                                                          
  20 import android.animation.Animator;                                                                       
  21 import android.animation.AnimatorListenerAdapter;                                                        
  22 import android.animation.AnimatorSet;                                                                    
  23 import android.animation.ObjectAnimator;                                                                 
  24 import android.animation.PropertyValuesHolder;                                                           
  25 import android.animation.TimeInterpolator;                                                               
  26 import android.animation.ValueAnimator;                                                                  
  27 import android.annotation.TargetApi;                                                                     
  28 import android.app.Activity;                                                                             
  29 import android.app.ActivityManager;                                                                      
  30 import android.app.ActivityOptions;                                                                      
  31 import android.app.AlertDialog;                                                                          
  32 import android.app.SearchManager;                                                                        
  33 import android.appwidget.AppWidgetHostView;                                                              
  34 import android.appwidget.AppWidgetManager;                                                               
  35 import android.appwidget.AppWidgetProviderInfo;                                                          
  36 import android.content.ActivityNotFoundException;                                                        
  37 import android.content.BroadcastReceiver;                                                                
  38 import android.content.ComponentCallbacks2;                                                              
  39 import android.content.ComponentName;                                                                    
  40 import android.content.ContentResolver;                                                                  
  41 import android.content.Context;                                                                          
  42 import android.content.DialogInterface;                                                                  
  43 import android.content.Intent;                                                                           
  44 import android.content.IntentFilter;                                                                     
  45 import android.content.SharedPreferences;                                                                
  46 import android.content.pm.ActivityInfo;                                                                  
  47 import android.content.pm.ApplicationInfo;                                                               
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.pm.PackageManager.NameNotFoundException;                                          
  50 import android.content.res.Configuration;                                                                
  51 import android.content.res.Resources;                                                                    
  52 import android.database.ContentObserver;                                                                 
  53 import android.graphics.Bitmap;                                                                          
  54 import android.graphics.Canvas;                                                                          
  55 import android.graphics.Color;                                                                           
  56 import android.graphics.Point;                                                                           
  57 import android.graphics.PorterDuff;                                                                      
  58 import android.graphics.Rect;                                                                            
  59 import android.graphics.drawable.Drawable;                                                               
  60 import android.net.Uri;                                                                                  
  61 import android.os.AsyncTask;                                                                             
  62 import android.os.Build;                                                                                 
  63 import android.os.Bundle;                                                                                
  64 import android.os.Environment;                                                                           
  65 import android.os.Handler;                                                                               
  66 import android.os.Message;                                                                               
  67 import android.os.StrictMode;                                                                            
  68 import android.os.SystemClock;                                                                           
  69 import android.speech.RecognizerIntent;                                                                  
  70 import android.text.Selection;                                                                           
  71 import android.text.SpannableStringBuilder;                                                              
  72 import android.text.TextUtils;                                                                           
  73 import android.text.method.TextKeyListener;                                                              
  74 import android.util.DisplayMetrics;                                                                      
  75 import android.util.Log;                                                                                 
  76 import android.view.ContextThemeWrapper;                                                                 
  77 import android.view.Display;                                                                             
  78 import android.view.Gravity;                                                                             
  79 import android.view.HapticFeedbackConstants;                                                             
  80 import android.view.KeyEvent;                                                                            
  81 import android.view.LayoutInflater;                                                                      
  82 import android.view.Menu;                                                                                
  83 import android.view.MotionEvent;                                                                         
  84 import android.view.Surface;                                                                             
  85 import android.view.View;                                                                                
  86 import android.view.View.OnClickListener;                                                                
  87 import android.view.View.OnLongClickListener;                                                            
  88 import android.view.ViewAnimationUtils;                                                                  
  89 import android.view.ViewGroup;                                                                           
  90 import android.view.ViewTreeObserver;                                                                    
  91 import android.view.ViewTreeObserver.OnGlobalLayoutListener;                                             
  92 import android.view.Window;                                                                              
  93 import android.view.WindowManager;                                                                       
  94 import android.view.accessibility.AccessibilityEvent;                                                    
  95 import android.view.animation.AccelerateInterpolator;                                                    
  96 import android.view.animation.DecelerateInterpolator;                                                    
  97 import android.view.animation.Interpolator;                                                              
  98 import android.view.inputmethod.InputMethodManager;                                                      
  99 import android.widget.Advanceable;                                                                       
 100 import android.widget.FrameLayout;                                                                       
 101 import android.widget.ImageView;                                                                         
 102 import android.widget.TextView;                                                                          
 103 import android.widget.Toast;                                                                             
 104                                                                                                          
 105 import com.android.launcher3.DropTarget.DragObject;                                                      
 106 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 107 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 108 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 109 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 110 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 111 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 112 import com.android.launcher3.compat.UserHandleCompat;                                                    
 113 import com.android.launcher3.compat.UserManagerCompat;                                                   
 114                                                                                                          
 115 import java.io.DataInputStream;                                                                          
 116 import java.io.DataOutputStream;                                                                         
 117 import java.io.File;                                                                                     
 118 import java.io.FileDescriptor;                                                                           
 119 import java.io.FileNotFoundException;                                                                    
 120 import java.io.FileOutputStream;                                                                         
 121 import java.io.IOException;                                                                              
 122 import java.io.PrintWriter;                                                                              
 123 import java.lang.reflect.Field;                                                                          
 124 import java.lang.reflect.InvocationTargetException;                                                      
 125 import java.lang.reflect.Method;                                                                         
 126 import java.text.DateFormat;                                                                             
 127 import java.util.ArrayList;                                                                              
 128 import java.util.Collection;                                                                             
 129 import java.util.Date;                                                                                   
 130 import java.util.HashMap;                                                                                
 131 import java.util.List;                                                                                   
 132 import java.util.concurrent.atomic.AtomicInteger;                                                        
 133                                                                                                          
 134 /**                                                                                                      
 135  * Default launcher application.                                                                         
 136  */                                                                                                      
 137 public class Launcher extends Activity                                                                   
 138         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 139                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {            
 140     static final String TAG = "Launcher";                                                                
 141     static final boolean LOGD = false;                                                                   
 142                                                                                                          
 143     static final boolean PROFILE_STARTUP = false;                                                        
 144     static final boolean DEBUG_WIDGETS = false;                                                          
 145     static final boolean DEBUG_STRICT_MODE = false;                                                      
 146     static final boolean DEBUG_RESUME_TIME = false;                                                      
 147     static final boolean DEBUG_DUMP_LOG = false;                                                         
 148                                                                                                          
 149     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 150                                                                                                          
 151     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 152     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 153     private static final int REQUEST_PICK_SHORTCUT = 7;                                                  
 154     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 155     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 156                                                                                                          
 157     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 158     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 159                                                                                                          
 160     /**                                                                                                  
 161      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 162      * request codes used internally.                                                                    
 163      */                                                                                                  
 164     protected static final int REQUEST_LAST = 100;                                                       
 165                                                                                                          
 166     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 167                                                                                                          
 168     static final int SCREEN_COUNT = 5;                                                                   
 169     static final int DEFAULT_SCREEN = 2;                                                                 
 170                                                                                                          
 171     private static final String PREFERENCES = "launcher.preferences";                                    
 172     // To turn on these properties, type                                                                 
 173     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 174     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                        
 175     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 176     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                
 177                                                                                                          
 178     // The Intent extra that defines whether to ignore the launch animation                              
 179     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 180             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 181                                                                                                          
 182     // Type: int                                                                                         
 183     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE = "launcher.state";                                        
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 190     // Type: int                                                                                         
 191     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 192     // Type: int                                                                                         
 193     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 194     // Type: boolean                                                                                     
 195     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 196     // Type: long                                                                                        
 197     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 198     // Type: int                                                                                         
 199     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 200     // Type: int                                                                                         
 201     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 202     // Type: parcelable                                                                                  
 203     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 204     // Type: parcelable                                                                                  
 205     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 206     // Type: int[]                                                                                       
 207     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 208                                                                                                          
 209     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 210     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 211                                                                                                          
 212     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 213     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 214             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 215                                                                                                          
 216     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";        
 217     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                      
 218             "com.android.launcher.toolbar_search_icon";                                                  
 219     private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                
 220             "com.android.launcher.toolbar_voice_search_icon";                                            
 221                                                                                                          
 222     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 223     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 224                                                                                                          
 225     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 226                                                                                                          
 227     /** The different states that Launcher can be in. */                                                 
 228     private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                
 229     private State mState = State.WORKSPACE;                                                              
 230     private AnimatorSet mStateAnimation;                                                                 
 231                                                                                                          
 232     private boolean mIsSafeModeEnabled;                                                                  
 233                                                                                                          
 234     static final int APPWIDGET_HOST_ID = 1024;                                                           
 235     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 236     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 237     private static final int ACTIVITY_START_DELAY = 1000;                                                
 238                                                                                                          
 239     private static final Object sLock = new Object();                                                    
 240     private static int sScreen = DEFAULT_SCREEN;                                                         
 241                                                                                                          
 242     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 243     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 244                                                                                                          
 245     // How long to wait before the new-shortcut animation automatically pans the workspace               
 246     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 247     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 248     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 249     private static final int SINGLE_FRAME_DELAY = 16;                                                    
 250                                                                                                          
 251     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 252             = new CloseSystemDialogsIntentReceiver();                                                    
 253     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 254                                                                                                          
 255     private LayoutInflater mInflater;                                                                    
 256                                                                                                          
 257     private Workspace mWorkspace;                                                                        
 258     private View mLauncherView;                                                                          
 259     private View mPageIndicators;                                                                        
 260     private DragLayer mDragLayer;                                                                        
 261     private DragController mDragController;                                                              
 262     private View mWeightWatcher;                                                                         
 263                                                                                                          
 264     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 265     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 266                                                                                                          
 267     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 268     private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                 
 269     private int mPendingAddWidgetId = -1;                                                                
 270                                                                                                          
 271     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 272                                                                                                          
 273     private FolderInfo mFolderInfo;                                                                      
 274                                                                                                          
 275     private Hotseat mHotseat;                                                                            
 276     private ViewGroup mOverviewPanel;                                                                    
 277                                                                                                          
 278     private View mAllAppsButton;                                                                         
 279                                                                                                          
 280     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 281     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 282     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 283     private boolean mAutoAdvanceRunning = false;                                                         
 284     private View mQsb;                                                                                   
 285                                                                                                          
 286     private Bundle mSavedState;                                                                          
 287     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 288     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 289     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 290     private State mOnResumeState = State.NONE;                                                           
 291                                                                                                          
 292     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 293                                                                                                          
 294     private boolean mWorkspaceLoading = true;                                                            
 295                                                                                                          
 296     private boolean mPaused = true;                                                                      
 297     private boolean mRestoring;                                                                          
 298     private boolean mWaitingForResult;                                                                   
 299     private boolean mOnResumeNeedsLoad;                                                                  
 300                                                                                                          
 301     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 302     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 303                                                                                                          
 304     private Bundle mSavedInstanceState;                                                                  
 305                                                                                                          
 306     private LauncherModel mModel;                                                                        
 307     private IconCache mIconCache;                                                                        
 308     private boolean mUserPresent = true;                                                                 
 309     private boolean mVisible = false;                                                                    
 310     private boolean mHasFocus = false;                                                                   
 311     private boolean mAttached = false;                                                                   
 312                                                                                                          
 313     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 314                                                                                                          
 315     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 316                                                                                                          
 317     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 318                                                                                                          
 319     // Related to the auto-advancing of widgets                                                          
 320     private final int ADVANCE_MSG = 1;                                                                   
 321     private final int mAdvanceInterval = 20000;                                                          
 322     private final int mAdvanceStagger = 250;                                                             
 323     private long mAutoAdvanceSentTime;                                                                   
 324     private long mAutoAdvanceTimeLeft = -1;                                                              
 325     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                     
 326         new HashMap<View, AppWidgetProviderInfo>();                                                      
 327                                                                                                          
 328     // Determines how long to wait after a rotation before restoring the screen orientation to           
 329     // match the sensor state.                                                                           
 330     private final int mRestoreScreenOrientationDelay = 500;                                              
 331                                                                                                          
 332     // External icons saved in case of resource changes, orientation, etc.                               
 333     private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];           
 334     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];            
 335                                                                                                          
 336     private Drawable mWorkspaceBackgroundDrawable;                                                       
 337                                                                                                          
 338     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 339     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 340                                                                                                          
 341     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 342     static Date sDateStamp = new Date();                                                                 
 343     static DateFormat sDateFormat =                                                                      
 344             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 345     static long sRunStart = System.currentTimeMillis();                                                  
 346     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 347                                                                                                          
 348     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 349     // it from the context.                                                                              
 350     private SharedPreferences mSharedPrefs;                                                              
 351                                                                                                          
 352     private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                   
 353                                                                                                          
 354     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 355     // when we scroll to that page on resume.                                                            
 356     private ImageView mFolderIconImageView;                                                              
 357     private Bitmap mFolderIconBitmap;                                                                    
 358     private Canvas mFolderIconCanvas;                                                                    
 359     private Rect mRectForFolderAnimation = new Rect();                                                   
 360                                                                                                          
 361     private BubbleTextView mWaitingForResume;                                                            
 362                                                                                                          
 363     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 364         public void run() {                                                                              
 365             if (mWorkspace != null) {                                                                    
 366                 mWorkspace.buildPageHardwareLayers();                                                    
 367             }                                                                                            
 368         }                                                                                                
 369     };                                                                                                   
 370                                                                                                          
 371     private static PendingAddArguments sPendingAddItem;                                                  
 372                                                                                                          
 373     public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);      
 374                                                                                                          
 375     private static class PendingAddArguments {                                                           
 376         int requestCode;                                                                                 
 377         Intent intent;                                                                                   
 378         long container;                                                                                  
 379         long screenId;                                                                                   
 380         int cellX;                                                                                       
 381         int cellY;                                                                                       
 382         int appWidgetId;                                                                                 
 383     }                                                                                                    
 384                                                                                                          
 385     private Stats mStats;                                                                                
 386                                                                                                          
 387     FocusIndicatorView mFocusHandler;                                                                    
 388                                                                                                          
 389     static boolean isPropertyEnabled(String propertyName) {                                              
 390         return Log.isLoggable(propertyName, Log.VERBOSE);                                                
 391     }                                                                                                    
 392                                                                                                          
 393     @Override                                                                                            
 394     protected void onCreate(Bundle savedInstanceState) {                                                 
 395         if (DEBUG_STRICT_MODE) {                                                                         
 396             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 397                     .detectDiskReads()                                                                   
 398                     .detectDiskWrites()                                                                  
 399                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 400                     .penaltyLog()                                                                        
 401                     .build());                                                                           
 402             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 403                     .detectLeakedSqlLiteObjects()                                                        
 404                     .detectLeakedClosableObjects()                                                       
 405                     .penaltyLog()                                                                        
 406                     .penaltyDeath()                                                                      
 407                     .build());                                                                           
 408         }                                                                                                
 409                                                                                                          
 410         super.onCreate(savedInstanceState);                                                              
 411                                                                                                          
 412         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 413         LauncherAppState app = LauncherAppState.getInstance();                                           
 414         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 415         // Determine the dynamic grid properties                                                         
 416         Point smallestSize = new Point();                                                                
 417         Point largestSize = new Point();                                                                 
 418         Point realSize = new Point();                                                                    
 419         Display display = getWindowManager().getDefaultDisplay();                                        
 420         display.getCurrentSizeRange(smallestSize, largestSize);                                          
 421         display.getRealSize(realSize);                                                                   
 422         DisplayMetrics dm = new DisplayMetrics();                                                        
 423         display.getMetrics(dm);                                                                          
 424                                                                                                          
 425         // Lazy-initialize the dynamic grid                                                              
 426         DeviceProfile grid = app.initDynamicGrid(this,                                                   
 427                 Math.min(smallestSize.x, smallestSize.y),                                                
 428                 Math.min(largestSize.x, largestSize.y),                                                  
 429                 realSize.x, realSize.y,                                                                  
 430                 dm.widthPixels, dm.heightPixels);                                                        
 431                                                                                                          
 432         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 433         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 434                 Context.MODE_PRIVATE);                                                                   
 435         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 436         mModel = app.setLauncher(this);                                                                  
 437         mIconCache = app.getIconCache();                                                                 
 438         mIconCache.flushInvalidIcons(grid);                                                              
 439         mDragController = new DragController(this);                                                      
 440         mInflater = getLayoutInflater();                                                                 
 441                                                                                                          
 442         mStats = new Stats(this);                                                                        
 443                                                                                                          
 444         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 445                                                                                                          
 446         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 447         mAppWidgetHost.startListening();                                                                 
 448                                                                                                          
 449         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 450         // this also ensures that any synchronous binding below doesn't re-trigger another               
 451         // LauncherModel load.                                                                           
 452         mPaused = false;                                                                                 
 453                                                                                                          
 454         if (PROFILE_STARTUP) {                                                                           
 455             android.os.Debug.startMethodTracing(                                                         
 456                     Environment.getExternalStorageDirectory() + "/launcher");                            
 457         }                                                                                                
 458                                                                                                          
 459         checkForLocaleChange();                                                                          
 460         setContentView(R.layout.launcher);                                                               
 461                                                                                                          
 462         setupViews();                                                                                    
 463         grid.layout(this);                                                                               
 464                                                                                                          
 465         registerContentObservers();                                                                      
 466                                                                                                          
 467         lockAllApps();                                                                                   
 468                                                                                                          
 469         mSavedState = savedInstanceState;                                                                
 470         restoreState(mSavedState);                                                                       
 471                                                                                                          
 472         if (PROFILE_STARTUP) {                                                                           
 473             android.os.Debug.stopMethodTracing();                                                        
 474         }                                                                                                
 475                                                                                                          
 476         if (!mRestoring) {                                                                               
 477             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 478                 // If the user leaves launcher, then we should just load items asynchronously when       
 479                 // they return.                                                                          
 480                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 481             } else {                                                                                     
 482                 // We only load the page synchronously if the user rotates (or triggers a                
 483                 // configuration change) while launcher is in the foreground                             
 484                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 485             }                                                                                            
 486         }                                                                                                
 487                                                                                                          
 488         // For handling default keys                                                                     
 489         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 490         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 491                                                                                                          
 492         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 493         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 494                                                                                                          
 495         updateGlobalIcons();                                                                             
 496                                                                                                          
 497         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 498         unlockScreenOrientation(true);                                                                   
 499                                                                                                          
 500         if (shouldShowIntroScreen()) {                                                                   
 501             showIntroScreen();                                                                           
 502         } else {                                                                                         
 503             showFirstRunActivity();                                                                      
 504             showFirstRunClings();                                                                        
 505         }                                                                                                
 506     }                                                                                                    
 507                                                                                                          
 508     @Override                                                                                            
 509     public void onLauncherProviderChange() { }                                                           
 510                                                                                                          
 511     /** To be overriden by subclasses to hint to Launcher that we have custom content */                 
 512     protected boolean hasCustomContentToLeft() {                                                         
 513         return false;                                                                                    
 514     }                                                                                                    
 515                                                                                                          
 516     /**                                                                                                  
 517      * To be overridden by subclasses to populate the custom content container and call                  
 518      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 519      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 520      */                                                                                                  
 521     protected void populateCustomContentContainer() {                                                    
 522     }                                                                                                    
 523                                                                                                          
 524     /**                                                                                                  
 525      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 526      * ensure the custom content page is added or removed if necessary.                                  
 527      */                                                                                                  
 528     protected void invalidateHasCustomContentToLeft() {                                                  
 529         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 530             // Not bound yet, wait for bindScreens to be called.                                         
 531             return;                                                                                      
 532         }                                                                                                
 533                                                                                                          
 534         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 535             // Create the custom content page and call the subclass to populate it.                      
 536             mWorkspace.createCustomContentContainer();                                                   
 537             populateCustomContentContainer();                                                            
 538         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 539             mWorkspace.removeCustomContentPage();                                                        
 540         }                                                                                                
 541     }                                                                                                    
 542                                                                                                          
 543     private void updateGlobalIcons() {                                                                   
 544         boolean searchVisible = false;                                                                   
 545         boolean voiceVisible = false;                                                                    
 546         // If we have a saved version of these external icons, we load them up immediately               
 547         int coi = getCurrentOrientationIndexForGlobalIcons();                                            
 548         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                           
 549             searchVisible = updateGlobalSearchIcon();                                                    
 550             voiceVisible = updateVoiceSearchIcon(searchVisible);                                         
 551         }                                                                                                
 552         if (sGlobalSearchIcon[coi] != null) {                                                            
 553              updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                             
 554              searchVisible = true;                                                                       
 555         }                                                                                                
 556         if (sVoiceSearchIcon[coi] != null) {                                                             
 557             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                
 558             voiceVisible = true;                                                                         
 559         }                                                                                                
 560         if (mSearchDropTargetBar != null) {                                                              
 561             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
 562         }                                                                                                
 563     }                                                                                                    
 564                                                                                                          
 565     private void checkForLocaleChange() {                                                                
 566         if (sLocaleConfiguration == null) {                                                              
 567             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 568                 @Override                                                                                
 569                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 570                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 571                     readConfiguration(Launcher.this, localeConfiguration);                               
 572                     return localeConfiguration;                                                          
 573                 }                                                                                        
 574                                                                                                          
 575                 @Override                                                                                
 576                 protected void onPostExecute(LocaleConfiguration result) {                               
 577                     sLocaleConfiguration = result;                                                       
 578                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 579                 }                                                                                        
 580             }.execute();                                                                                 
 581             return;                                                                                      
 582         }                                                                                                
 583                                                                                                          
 584         final Configuration configuration = getResources().getConfiguration();                           
 585                                                                                                          
 586         final String previousLocale = sLocaleConfiguration.locale;                                       
 587         final String locale = configuration.locale.toString();                                           
 588                                                                                                          
 589         final int previousMcc = sLocaleConfiguration.mcc;                                                
 590         final int mcc = configuration.mcc;                                                               
 591                                                                                                          
 592         final int previousMnc = sLocaleConfiguration.mnc;                                                
 593         final int mnc = configuration.mnc;                                                               
 594                                                                                                          
 595         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 596                                                                                                          
 597         if (localeChanged) {                                                                             
 598             sLocaleConfiguration.locale = locale;                                                        
 599             sLocaleConfiguration.mcc = mcc;                                                              
 600             sLocaleConfiguration.mnc = mnc;                                                              
 601                                                                                                          
 602             mIconCache.flush();                                                                          
 603                                                                                                          
 604             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 605             new AsyncTask<Void, Void, Void>() {                                                          
 606                 public Void doInBackground(Void ... args) {                                              
 607                     writeConfiguration(Launcher.this, localeConfiguration);                              
 608                     return null;                                                                         
 609                 }                                                                                        
 610             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 611         }                                                                                                
 612     }                                                                                                    
 613                                                                                                          
 614     private static class LocaleConfiguration {                                                           
 615         public String locale;                                                                            
 616         public int mcc = -1;                                                                             
 617         public int mnc = -1;                                                                             
 618     }                                                                                                    
 619                                                                                                          
 620     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 621         DataInputStream in = null;                                                                       
 622         try {                                                                                            
 623             in = new DataInputStream(context.openFileInput(PREFERENCES));                                
 624             configuration.locale = in.readUTF();                                                         
 625             configuration.mcc = in.readInt();                                                            
 626             configuration.mnc = in.readInt();                                                            
 627         } catch (FileNotFoundException e) {                                                              
 628             // Ignore                                                                                    
 629         } catch (IOException e) {                                                                        
 630             // Ignore                                                                                    
 631         } finally {                                                                                      
 632             if (in != null) {                                                                            
 633                 try {                                                                                    
 634                     in.close();                                                                          
 635                 } catch (IOException e) {                                                                
 636                     // Ignore                                                                            
 637                 }                                                                                        
 638             }                                                                                            
 639         }                                                                                                
 640     }                                                                                                    
 641                                                                                                          
 642     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 643         DataOutputStream out = null;                                                                     
 644         try {                                                                                            
 645             out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));               
 646             out.writeUTF(configuration.locale);                                                          
 647             out.writeInt(configuration.mcc);                                                             
 648             out.writeInt(configuration.mnc);                                                             
 649             out.flush();                                                                                 
 650         } catch (FileNotFoundException e) {                                                              
 651             // Ignore                                                                                    
 652         } catch (IOException e) {                                                                        
 653             //noinspection ResultOfMethodCallIgnored                                                     
 654             context.getFileStreamPath(PREFERENCES).delete();                                             
 655         } finally {                                                                                      
 656             if (out != null) {                                                                           
 657                 try {                                                                                    
 658                     out.close();                                                                         
 659                 } catch (IOException e) {                                                                
 660                     // Ignore                                                                            
 661                 }                                                                                        
 662             }                                                                                            
 663         }                                                                                                
 664     }                                                                                                    
 665                                                                                                          
 666     public Stats getStats() {                                                                            
 667         return mStats;                                                                                   
 668     }                                                                                                    
 669                                                                                                          
 670     public LayoutInflater getInflater() {                                                                
 671         return mInflater;                                                                                
 672     }                                                                                                    
 673                                                                                                          
 674     boolean isDraggingEnabled() {                                                                        
 675         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 676         // that is subsequently removed from the workspace in startBinding().                            
 677         return !mModel.isLoadingWorkspace();                                                             
 678     }                                                                                                    
 679                                                                                                          
 680     static int getScreen() {                                                                             
 681         synchronized (sLock) {                                                                           
 682             return sScreen;                                                                              
 683         }                                                                                                
 684     }                                                                                                    
 685                                                                                                          
 686     static void setScreen(int screen) {                                                                  
 687         synchronized (sLock) {                                                                           
 688             sScreen = screen;                                                                            
 689         }                                                                                                
 690     }                                                                                                    
 691                                                                                                          
 692     public static int generateViewId() {                                                                 
 693         if (Build.VERSION.SDK_INT >= 17) {                                                               
 694             return View.generateViewId();                                                                
 695         } else {                                                                                         
 696             // View.generateViewId() is not available. The following fallback logic is a copy            
 697             // of its implementation.                                                                    
 698             for (;;) {                                                                                   
 699                 final int result = sNextGeneratedId.get();                                               
 700                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 701                 int newValue = result + 1;                                                               
 702                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 703                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 704                     return result;                                                                       
 705                 }                                                                                        
 706             }                                                                                            
 707         }                                                                                                
 708     }                                                                                                    
 709                                                                                                          
 710     public int getViewIdForItem(ItemInfo info) {                                                         
 711         // This cast is safe given the > 2B range for int.                                               
 712         int itemId = (int) info.id;                                                                      
 713         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 714             return mItemIdToViewId.get(itemId);                                                          
 715         }                                                                                                
 716         int viewId = generateViewId();                                                                   
 717         mItemIdToViewId.put(itemId, viewId);                                                             
 718         return viewId;                                                                                   
 719     }                                                                                                    
 720                                                                                                          
 721     /**                                                                                                  
 722      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 723      * a configuration step, this allows the proper animations to run after other transitions.           
 724      */                                                                                                  
 725     private long completeAdd(PendingAddArguments args) {                                                 
 726         long screenId = args.screenId;                                                                   
 727         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 728             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 729             // that the drop page actually exists.                                                       
 730             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 731         }                                                                                                
 732                                                                                                          
 733         switch (args.requestCode) {                                                                      
 734             case REQUEST_CREATE_SHORTCUT:                                                                
 735                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 736                         args.cellY);                                                                     
 737                 break;                                                                                   
 738             case REQUEST_CREATE_APPWIDGET:                                                               
 739                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 740                 break;                                                                                   
 741             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 742                 completeRestoreAppWidget(args.appWidgetId);                                              
 743                 break;                                                                                   
 744         }                                                                                                
 745         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 746         // if you turned the screen off and then back while in All Apps, Launcher would not              
 747         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 748         resetAddInfo();                                                                                  
 749         return screenId;                                                                                 
 750     }                                                                                                    
 751                                                                                                          
 752     @Override                                                                                            
 753     protected void onActivityResult(                                                                     
 754             final int requestCode, final int resultCode, final Intent data) {                            
 755         // Reset the startActivity waiting flag                                                          
 756         setWaitingForResult(false);                                                                      
 757         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 758         mPendingAddWidgetId = -1;                                                                        
 759                                                                                                          
 760         Runnable exitSpringLoaded = new Runnable() {                                                     
 761             @Override                                                                                    
 762             public void run() {                                                                          
 763                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 764                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 765             }                                                                                            
 766         };                                                                                               
 767                                                                                                          
 768         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 769             final int appWidgetId = data != null ?                                                       
 770                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 771             if (resultCode == RESULT_CANCELED) {                                                         
 772                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 773                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 774                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 775             } else if (resultCode == RESULT_OK) {                                                        
 776                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 777                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 778             }                                                                                            
 779             return;                                                                                      
 780         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 781             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 782                 mWorkspace.exitOverviewMode(false);                                                      
 783             }                                                                                            
 784             return;                                                                                      
 785         }                                                                                                
 786                                                                                                          
 787         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 788                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 789                                                                                                          
 790         final boolean workspaceLocked = isWorkspaceLocked();                                             
 791         // We have special handling for widgets                                                          
 792         if (isWidgetDrop) {                                                                              
 793             final int appWidgetId;                                                                       
 794             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 795                     : -1;                                                                                
 796             if (widgetId < 0) {                                                                          
 797                 appWidgetId = pendingAddWidgetId;                                                        
 798             } else {                                                                                     
 799                 appWidgetId = widgetId;                                                                  
 800             }                                                                                            
 801                                                                                                          
 802             final int result;                                                                            
 803             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 804                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 805                         "returned from the widget configuration activity.");                             
 806                 result = RESULT_CANCELED;                                                                
 807                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 808                 final Runnable onComplete = new Runnable() {                                             
 809                     @Override                                                                            
 810                     public void run() {                                                                  
 811                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 812                     }                                                                                    
 813                 };                                                                                       
 814                 if (workspaceLocked) {                                                                   
 815                     // No need to remove the empty screen if we're mid-binding, as the                   
 816                     // the bind will not add the empty screen.                                           
 817                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 818                 } else {                                                                                 
 819                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 820                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 821                 }                                                                                        
 822             } else {                                                                                     
 823                 if (!workspaceLocked) {                                                                  
 824                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 825                         // When the screen id represents an actual screen (as opposed to a rank)         
 826                         // we make sure that the drop page actually exists.                              
 827                         mPendingAddInfo.screenId =                                                       
 828                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 829                     }                                                                                    
 830                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 831                                                                                                          
 832                     dropLayout.setDropPending(true);                                                     
 833                     final Runnable onComplete = new Runnable() {                                         
 834                         @Override                                                                        
 835                         public void run() {                                                              
 836                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 837                             dropLayout.setDropPending(false);                                            
 838                         }                                                                                
 839                     };                                                                                   
 840                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 841                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 842                 } else {                                                                                 
 843                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 844                             mPendingAddInfo);                                                            
 845                     sPendingAddItem = args;                                                              
 846                 }                                                                                        
 847             }                                                                                            
 848             return;                                                                                      
 849         }                                                                                                
 850                                                                                                          
 851         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 852             if (resultCode == RESULT_OK) {                                                               
 853                 // Update the widget view.                                                               
 854                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 855                         pendingAddWidgetId, mPendingAddInfo);                                            
 856                 if (workspaceLocked) {                                                                   
 857                     sPendingAddItem = args;                                                              
 858                 } else {                                                                                 
 859                     completeAdd(args);                                                                   
 860                 }                                                                                        
 861             }                                                                                            
 862             // Leave the widget in the pending state if the user canceled the configure.                 
 863             return;                                                                                      
 864         }                                                                                                
 865                                                                                                          
 866         // The pattern used here is that a user PICKs a specific application,                            
 867         // which, depending on the target, might need to CREATE the actual target.                       
 868                                                                                                          
 869         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 870         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 871         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 872             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 873                     mPendingAddInfo);                                                                    
 874             if (isWorkspaceLocked()) {                                                                   
 875                 sPendingAddItem = args;                                                                  
 876             } else {                                                                                     
 877                 completeAdd(args);                                                                       
 878                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 879                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 880             }                                                                                            
 881         } else if (resultCode == RESULT_CANCELED) {                                                      
 882             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 883                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 884         }                                                                                                
 885         mDragLayer.clearAnimatedView();                                                                  
 886     }                                                                                                    
 887                                                                                                          
 888     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 889             appWidgetId, ItemInfo info) {                                                                
 890         PendingAddArguments args = new PendingAddArguments();                                            
 891         args.requestCode = requestCode;                                                                  
 892         args.intent = data;                                                                              
 893         args.container = info.container;                                                                 
 894         args.screenId = info.screenId;                                                                   
 895         args.cellX = info.cellX;                                                                         
 896         args.cellY = info.cellY;                                                                         
 897         args.appWidgetId = appWidgetId;                                                                  
 898         return args;                                                                                     
 899     }                                                                                                    
 900                                                                                                          
 901     /**                                                                                                  
 902      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 903      *                                                                                                   
 904      * @param screenId the screen id to check                                                            
 905      * @return the new screen, or screenId if it exists                                                  
 906      */                                                                                                  
 907     private long ensurePendingDropLayoutExists(long screenId) {                                          
 908         CellLayout dropLayout =                                                                          
 909                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 910         if (dropLayout == null) {                                                                        
 911             // it's possible that the add screen was removed because it was                              
 912             // empty and a re-bind occurred                                                              
 913             mWorkspace.addExtraEmptyScreen();                                                            
 914             return mWorkspace.commitExtraEmptyScreen();                                                  
 915         } else {                                                                                         
 916             return screenId;                                                                             
 917         }                                                                                                
 918     }                                                                                                    
 919                                                                                                          
 920     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 921         CellLayout cellLayout =                                                                          
 922                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 923         Runnable onCompleteRunnable = null;                                                              
 924         int animationType = 0;                                                                           
 925                                                                                                          
 926         AppWidgetHostView boundWidget = null;                                                            
 927         if (resultCode == RESULT_OK) {                                                                   
 928             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 929             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 930                     mPendingAddWidgetInfo);                                                              
 931             boundWidget = layout;                                                                        
 932             onCompleteRunnable = new Runnable() {                                                        
 933                 @Override                                                                                
 934                 public void run() {                                                                      
 935                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 936                             mPendingAddInfo.screenId, layout, null);                                     
 937                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 938                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 939                 }                                                                                        
 940             };                                                                                           
 941         } else if (resultCode == RESULT_CANCELED) {                                                      
 942             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 943             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 944         }                                                                                                
 945         if (mDragLayer.getAnimatedView() != null) {                                                      
 946             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 947                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 948                     animationType, boundWidget, true);                                                   
 949         } else if (onCompleteRunnable != null) {                                                         
 950             // The animated view may be null in the case of a rotation during widget configuration       
 951             onCompleteRunnable.run();                                                                    
 952         }                                                                                                
 953     }                                                                                                    
 954                                                                                                          
 955     @Override                                                                                            
 956     protected void onStop() {                                                                            
 957         super.onStop();                                                                                  
 958         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 959     }                                                                                                    
 960                                                                                                          
 961     @Override                                                                                            
 962     protected void onStart() {                                                                           
 963         super.onStart();                                                                                 
 964         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 965     }                                                                                                    
 966                                                                                                          
 967     @Override                                                                                            
 968     protected void onResume() {                                                                          
 969         long startTime = 0;                                                                              
 970         if (DEBUG_RESUME_TIME) {                                                                         
 971             startTime = System.currentTimeMillis();                                                      
 972             Log.v(TAG, "Launcher.onResume()");                                                           
 973         }                                                                                                
 974         super.onResume();                                                                                
 975                                                                                                          
 976         // Restore the previous launcher state                                                           
 977         if (mOnResumeState == State.WORKSPACE) {                                                         
 978             showWorkspace(false);                                                                        
 979         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                             
 980             showAllApps(false, mAppsCustomizeContent.getContentType(), false);                           
 981         }                                                                                                
 982         mOnResumeState = State.NONE;                                                                     
 983                                                                                                          
 984         // Background was set to gradient in onPause(), restore to black if in all apps.                 
 985         setWorkspaceBackground(mState == State.WORKSPACE);                                               
 986                                                                                                          
 987         mPaused = false;                                                                                 
 988         if (mRestoring || mOnResumeNeedsLoad) {                                                          
 989             setWorkspaceLoading(true);                                                                   
 990             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
 991             mRestoring = false;                                                                          
 992             mOnResumeNeedsLoad = false;                                                                  
 993         }                                                                                                
 994         if (mBindOnResumeCallbacks.size() > 0) {                                                         
 995             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
 996             // execute them here                                                                         
 997             long startTimeCallbacks = 0;                                                                 
 998             if (DEBUG_RESUME_TIME) {                                                                     
 999                 startTimeCallbacks = System.currentTimeMillis();                                         
1000             }                                                                                            
1001                                                                                                          
1002             if (mAppsCustomizeContent != null) {                                                         
1003                 mAppsCustomizeContent.setBulkBind(true);                                                 
1004             }                                                                                            
1005             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1006                 mBindOnResumeCallbacks.get(i).run();                                                     
1007             }                                                                                            
1008             if (mAppsCustomizeContent != null) {                                                         
1009                 mAppsCustomizeContent.setBulkBind(false);                                                
1010             }                                                                                            
1011             mBindOnResumeCallbacks.clear();                                                              
1012             if (DEBUG_RESUME_TIME) {                                                                     
1013                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1014                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1015             }                                                                                            
1016         }                                                                                                
1017         if (mOnResumeCallbacks.size() > 0) {                                                             
1018             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1019                 mOnResumeCallbacks.get(i).run();                                                         
1020             }                                                                                            
1021             mOnResumeCallbacks.clear();                                                                  
1022         }                                                                                                
1023                                                                                                          
1024         // Reset the pressed state of icons that were locked in the press state while activities         
1025         // were launching                                                                                
1026         if (mWaitingForResume != null) {                                                                 
1027             // Resets the previous workspace icon press state                                            
1028             mWaitingForResume.setStayPressed(false);                                                     
1029         }                                                                                                
1030                                                                                                          
1031         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1032         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1033         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1034         // orientation.                                                                                  
1035         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1036                                                                                                          
1037         // Process any items that were added while Launcher was away.                                    
1038         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1039                                                                                                          
1040         // Update the voice search button proxy                                                          
1041         updateVoiceButtonProxyVisible(false);                                                            
1042                                                                                                          
1043         // Again, as with the above scenario, it's possible that one or more of the global icons         
1044         // were updated in the wrong orientation.                                                        
1045         updateGlobalIcons();                                                                             
1046         if (DEBUG_RESUME_TIME) {                                                                         
1047             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1048         }                                                                                                
1049                                                                                                          
1050         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1051             // If we are resuming and the custom content is the current page, we call onShow().          
1052             // It is also poassible that onShow will instead be called slightly after first layout       
1053             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1054             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1055                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1056             }                                                                                            
1057         }                                                                                                
1058         mWorkspace.updateInteractionForState();                                                          
1059         mWorkspace.onResume();                                                                           
1060                                                                                                          
1061         PackageInstallerCompat.getInstance(this).onResume();                                             
1062     }                                                                                                    
1063                                                                                                          
1064     @Override                                                                                            
1065     protected void onPause() {                                                                           
1066         // Ensure that items added to Launcher are queued until Launcher returns                         
1067         InstallShortcutReceiver.enableInstallQueue();                                                    
1068         PackageInstallerCompat.getInstance(this).onPause();                                              
1069                                                                                                          
1070         super.onPause();                                                                                 
1071         mPaused = true;                                                                                  
1072         mDragController.cancelDrag();                                                                    
1073         mDragController.resetLastGestureUpTime();                                                        
1074                                                                                                          
1075         // We call onHide() aggressively. The custom content callbacks should be able to                 
1076         // debounce excess onHide calls.                                                                 
1077         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1078             mWorkspace.getCustomContentCallbacks().onHide();                                             
1079         }                                                                                                
1080     }                                                                                                    
1081                                                                                                          
1082     QSBScroller mQsbScroller = new QSBScroller() {                                                       
1083         int scrollY = 0;                                                                                 
1084                                                                                                          
1085         @Override                                                                                        
1086         public void setScrollY(int scroll) {                                                             
1087             scrollY = scroll;                                                                            
1088                                                                                                          
1089             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1090                 mSearchDropTargetBar.setTranslationY(- scrollY);                                         
1091                 getQsbBar().setTranslationY(-scrollY);                                                   
1092             }                                                                                            
1093         }                                                                                                
1094     };                                                                                                   
1095                                                                                                          
1096     public void resetQSBScroll() {                                                                       
1097         mSearchDropTargetBar.animate().translationY(0).start();                                          
1098         getQsbBar().animate().translationY(0).start();                                                   
1099     }                                                                                                    
1100                                                                                                          
1101     public interface CustomContentCallbacks {                                                            
1102         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1103         // by a onResume or by scrolling otherwise.                                                      
1104         public void onShow(boolean fromResume);                                                          
1105                                                                                                          
1106         // Custom content is completely hidden                                                           
1107         public void onHide();                                                                            
1108                                                                                                          
1109         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1110         public void onScrollProgressChanged(float progress);                                             
1111                                                                                                          
1112         // Indicates whether the user is allowed to scroll away from the custom content.                 
1113         boolean isScrollingAllowed();                                                                    
1114     }                                                                                                    
1115                                                                                                          
1116     protected boolean hasSettings() {                                                                    
1117         return false;                                                                                    
1118     }                                                                                                    
1119                                                                                                          
1120     public interface QSBScroller {                                                                       
1121         public void setScrollY(int scrollY);                                                             
1122     }                                                                                                    
1123                                                                                                          
1124     public QSBScroller addToCustomContentPage(View customContent,                                        
1125             CustomContentCallbacks callbacks, String description) {                                      
1126         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1127         return mQsbScroller;                                                                             
1128     }                                                                                                    
1129                                                                                                          
1130     // The custom content needs to offset its content to account for the QSB                             
1131     public int getTopOffsetForCustomContent() {                                                          
1132         return mWorkspace.getPaddingTop();                                                               
1133     }                                                                                                    
1134                                                                                                          
1135     @Override                                                                                            
1136     public Object onRetainNonConfigurationInstance() {                                                   
1137         // Flag the loader to stop early before switching                                                
1138         if (mModel.isCurrentCallbacks(this)) {                                                           
1139             mModel.stopLoader();                                                                         
1140         }                                                                                                
1141         if (mAppsCustomizeContent != null) {                                                             
1142             mAppsCustomizeContent.surrender();                                                           
1143         }                                                                                                
1144         return Boolean.TRUE;                                                                             
1145     }                                                                                                    
1146                                                                                                          
1147     // We can't hide the IME if it was forced open.  So don't bother                                     
1148     @Override                                                                                            
1149     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1150         super.onWindowFocusChanged(hasFocus);                                                            
1151         mHasFocus = hasFocus;                                                                            
1152     }                                                                                                    
1153                                                                                                          
1154     private boolean acceptFilter() {                                                                     
1155         final InputMethodManager inputManager = (InputMethodManager)                                     
1156                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1157         return !inputManager.isFullscreenMode();                                                         
1158     }                                                                                                    
1159                                                                                                          
1160     @Override                                                                                            
1161     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1162         final int uniChar = event.getUnicodeChar();                                                      
1163         final boolean handled = super.onKeyDown(keyCode, event);                                         
1164         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1165         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1166             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1167                     keyCode, event);                                                                     
1168             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1169                 // something usable has been typed - start a search                                      
1170                 // the typed text will be retrieved and cleared by                                       
1171                 // showSearchDialog()                                                                    
1172                 // If there are multiple keystrokes before the search dialog takes focus,                
1173                 // onSearchRequested() will be called for every keystroke,                               
1174                 // but it is idempotent, so it's fine.                                                   
1175                 return onSearchRequested();                                                              
1176             }                                                                                            
1177         }                                                                                                
1178                                                                                                          
1179         // Eat the long press event so the keyboard doesn't come up.                                     
1180         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1181             return true;                                                                                 
1182         }                                                                                                
1183                                                                                                          
1184         return handled;                                                                                  
1185     }                                                                                                    
1186                                                                                                          
1187     private String getTypedText() {                                                                      
1188         return mDefaultKeySsb.toString();                                                                
1189     }                                                                                                    
1190                                                                                                          
1191     private void clearTypedText() {                                                                      
1192         mDefaultKeySsb.clear();                                                                          
1193         mDefaultKeySsb.clearSpans();                                                                     
1194         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1195     }                                                                                                    
1196                                                                                                          
1197     /**                                                                                                  
1198      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1199      * State                                                                                             
1200      */                                                                                                  
1201     private static State intToState(int stateOrdinal) {                                                  
1202         State state = State.WORKSPACE;                                                                   
1203         final State[] stateValues = State.values();                                                      
1204         for (int i = 0; i < stateValues.length; i++) {                                                   
1205             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1206                 state = stateValues[i];                                                                  
1207                 break;                                                                                   
1208             }                                                                                            
1209         }                                                                                                
1210         return state;                                                                                    
1211     }                                                                                                    
1212                                                                                                          
1213     /**                                                                                                  
1214      * Restores the previous state, if it exists.                                                        
1215      *                                                                                                   
1216      * @param savedState The previous state.                                                             
1217      */                                                                                                  
1218     @SuppressWarnings("unchecked")                                                                       
1219     private void restoreState(Bundle savedState) {                                                       
1220         if (savedState == null) {                                                                        
1221             return;                                                                                      
1222         }                                                                                                
1223                                                                                                          
1224         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1225         if (state == State.APPS_CUSTOMIZE) {                                                             
1226             mOnResumeState = State.APPS_CUSTOMIZE;                                                       
1227         }                                                                                                
1228                                                                                                          
1229         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1230                 PagedView.INVALID_RESTORE_PAGE);                                                         
1231         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1232             mWorkspace.setRestorePage(currentScreen);                                                    
1233         }                                                                                                
1234                                                                                                          
1235         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1236         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1237                                                                                                          
1238         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1239             mPendingAddInfo.container = pendingAddContainer;                                             
1240             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1241             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1242             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1243             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1244             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1245             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1246             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1247             setWaitingForResult(true);                                                                   
1248             mRestoring = true;                                                                           
1249         }                                                                                                
1250                                                                                                          
1251         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1252         if (renameFolder) {                                                                              
1253             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1254             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1255             mRestoring = true;                                                                           
1256         }                                                                                                
1257                                                                                                          
1258         // Restore the AppsCustomize tab                                                                 
1259         if (mAppsCustomizeTabHost != null) {                                                             
1260             String curTab = savedState.getString("apps_customize_currentTab");                           
1261             if (curTab != null) {                                                                        
1262                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1263                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1264                 mAppsCustomizeContent.loadAssociatedPages(                                               
1265                         mAppsCustomizeContent.getCurrentPage());                                         
1266             }                                                                                            
1267                                                                                                          
1268             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1269             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1270         }                                                                                                
1271         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1272                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1273     }                                                                                                    
1274                                                                                                          
1275     /**                                                                                                  
1276      * Finds all the views we need and configure them properly.                                          
1277      */                                                                                                  
1278     private void setupViews() {                                                                          
1279         final DragController dragController = mDragController;                                           
1280                                                                                                          
1281         mLauncherView = findViewById(R.id.launcher);                                                     
1282         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1283         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1284         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1285         mWorkspace.setPageSwitchListener(this);                                                          
1286         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1287                                                                                                          
1288         mLauncherView.setSystemUiVisibility(                                                             
1289                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1290         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1291                                                                                                          
1292         // Setup the drag layer                                                                          
1293         mDragLayer.setup(this, dragController);                                                          
1294                                                                                                          
1295         // Setup the hotseat                                                                             
1296         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1297         if (mHotseat != null) {                                                                          
1298             mHotseat.setup(this);                                                                        
1299             mHotseat.setOnLongClickListener(this);                                                       
1300         }                                                                                                
1301                                                                                                          
1302         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1303         View widgetButton = findViewById(R.id.widget_button);                                            
1304         widgetButton.setOnClickListener(new OnClickListener() {                                          
1305             @Override                                                                                    
1306             public void onClick(View arg0) {                                                             
1307                 if (!mWorkspace.isSwitchingState()) {                                                    
1308                     onClickAddWidgetButton(arg0);                                                        
1309                 }                                                                                        
1310             }                                                                                            
1311         });                                                                                              
1312         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1313                                                                                                          
1314         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1315         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1316             @Override                                                                                    
1317             public void onClick(View arg0) {                                                             
1318                 if (!mWorkspace.isSwitchingState()) {                                                    
1319                     onClickWallpaperPicker(arg0);                                                        
1320                 }                                                                                        
1321             }                                                                                            
1322         });                                                                                              
1323         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1324                                                                                                          
1325         View settingsButton = findViewById(R.id.settings_button);                                        
1326         if (hasSettings()) {                                                                             
1327             settingsButton.setOnClickListener(new OnClickListener() {                                    
1328                 @Override                                                                                
1329                 public void onClick(View arg0) {                                                         
1330                     if (!mWorkspace.isSwitchingState()) {                                                
1331                         onClickSettingsButton(arg0);                                                     
1332                     }                                                                                    
1333                 }                                                                                        
1334             });                                                                                          
1335             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1336         } else {                                                                                         
1337             settingsButton.setVisibility(View.GONE);                                                     
1338             FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();     
1339             lp.gravity = Gravity.END | Gravity.TOP;                                                      
1340             widgetButton.requestLayout();                                                                
1341         }                                                                                                
1342                                                                                                          
1343         mOverviewPanel.setAlpha(0f);                                                                     
1344                                                                                                          
1345         // Setup the workspace                                                                           
1346         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1347         mWorkspace.setOnLongClickListener(this);                                                         
1348         mWorkspace.setup(dragController);                                                                
1349         dragController.addDragListener(mWorkspace);                                                      
1350                                                                                                          
1351         // Get the search/delete bar                                                                     
1352         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1353                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1354                                                                                                          
1355         // Setup AppsCustomize                                                                           
1356         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1357         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1358                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1359         mAppsCustomizeContent.setup(this, dragController);                                               
1360                                                                                                          
1361         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1362         dragController.setDragScoller(mWorkspace);                                                       
1363         dragController.setScrollView(mDragLayer);                                                        
1364         dragController.setMoveTarget(mWorkspace);                                                        
1365         dragController.addDropTarget(mWorkspace);                                                        
1366         if (mSearchDropTargetBar != null) {                                                              
1367             mSearchDropTargetBar.setup(this, dragController);                                            
1368         }                                                                                                
1369                                                                                                          
1370         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1371             Log.v(TAG, "adding WeightWatcher");                                                          
1372             mWeightWatcher = new WeightWatcher(this);                                                    
1373             mWeightWatcher.setAlpha(0.5f);                                                               
1374             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1375                     new FrameLayout.LayoutParams(                                                        
1376                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1377                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1378                             Gravity.BOTTOM)                                                              
1379             );                                                                                           
1380                                                                                                          
1381             boolean show = shouldShowWeightWatcher();                                                    
1382             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1383         }                                                                                                
1384     }                                                                                                    
1385                                                                                                          
1386     /**                                                                                                  
1387      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1388      */                                                                                                  
1389     public void setAllAppsButton(View allAppsButton) {                                                   
1390         mAllAppsButton = allAppsButton;                                                                  
1391     }                                                                                                    
1392                                                                                                          
1393     public View getAllAppsButton() {                                                                     
1394         return mAllAppsButton;                                                                           
1395     }                                                                                                    
1396                                                                                                          
1397     /**                                                                                                  
1398      * Creates a view representing a shortcut.                                                           
1399      *                                                                                                   
1400      * @param info The data structure describing the shortcut.                                           
1401      *                                                                                                   
1402      * @return A View inflated from R.layout.application.                                                
1403      */                                                                                                  
1404     View createShortcut(ShortcutInfo info) {                                                             
1405         return createShortcut(R.layout.application,                                                      
1406                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1407     }                                                                                                    
1408                                                                                                          
1409     /**                                                                                                  
1410      * Creates a view representing a shortcut inflated from the specified resource.                      
1411      *                                                                                                   
1412      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1413      * @param parent The group the shortcut belongs to.                                                  
1414      * @param info The data structure describing the shortcut.                                           
1415      *                                                                                                   
1416      * @return A View inflated from layoutResId.                                                         
1417      */                                                                                                  
1418     View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                          
1419         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1420         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1421         favorite.setOnClickListener(this);                                                               
1422         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1423         return favorite;                                                                                 
1424     }                                                                                                    
1425                                                                                                          
1426     /**                                                                                                  
1427      * Add a shortcut to the workspace.                                                                  
1428      *                                                                                                   
1429      * @param data The intent describing the shortcut.                                                   
1430      * @param cellInfo The position on screen where to create the shortcut.                              
1431      */                                                                                                  
1432     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1433             int cellY) {                                                                                 
1434         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1435         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1436         CellLayout layout = getCellLayout(container, screenId);                                          
1437                                                                                                          
1438         boolean foundCellSpan = false;                                                                   
1439                                                                                                          
1440         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                             
1441         if (info == null) {                                                                              
1442             return;                                                                                      
1443         }                                                                                                
1444         final View view = createShortcut(info);                                                          
1445                                                                                                          
1446         // First we check if we already know the exact location where we want to add this item.          
1447         if (cellX >= 0 && cellY >= 0) {                                                                  
1448             cellXY[0] = cellX;                                                                           
1449             cellXY[1] = cellY;                                                                           
1450             foundCellSpan = true;                                                                        
1451                                                                                                          
1452             // If appropriate, either create a folder or add to an existing folder                       
1453             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1454                     true, null,null)) {                                                                  
1455                 return;                                                                                  
1456             }                                                                                            
1457             DragObject dragObject = new DragObject();                                                    
1458             dragObject.dragInfo = info;                                                                  
1459             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1460                     true)) {                                                                             
1461                 return;                                                                                  
1462             }                                                                                            
1463         } else if (touchXY != null) {                                                                    
1464             // when dragging and dropping, just find the closest free spot                               
1465             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1466             foundCellSpan = (result != null);                                                            
1467         } else {                                                                                         
1468             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1469         }                                                                                                
1470                                                                                                          
1471         if (!foundCellSpan) {                                                                            
1472             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1473             return;                                                                                      
1474         }                                                                                                
1475                                                                                                          
1476         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1477                                                                                                          
1478         if (!mRestoring) {                                                                               
1479             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1480                     isWorkspaceLocked());                                                                
1481         }                                                                                                
1482     }                                                                                                    
1483                                                                                                          
1484     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1485             int minHeight) {                                                                             
1486         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1487         // We want to account for the extra amount of padding that we are adding to the widget           
1488         // to ensure that it gets the full amount of space that it has requested                         
1489         int requiredWidth = minWidth + padding.left + padding.right;                                     
1490         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1491         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1492     }                                                                                                    
1493                                                                                                          
1494     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1495         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1496     }                                                                                                    
1497                                                                                                          
1498     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1499         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1500     }                                                                                                    
1501                                                                                                          
1502     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1503         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1504     }                                                                                                    
1505                                                                                                          
1506     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1507         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1508                 info.minResizeHeight);                                                                   
1509     }                                                                                                    
1510                                                                                                          
1511     /**                                                                                                  
1512      * Add a widget to the workspace.                                                                    
1513      *                                                                                                   
1514      * @param appWidgetId The app widget id                                                              
1515      * @param cellInfo The position on screen where to create the widget.                                
1516      */                                                                                                  
1517     private void completeAddAppWidget(final int appWidgetId, long container, long screenId,              
1518             AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                           
1519         if (appWidgetInfo == null) {                                                                     
1520             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
1521         }                                                                                                
1522                                                                                                          
1523         // Calculate the grid spans needed to fit this widget                                            
1524         CellLayout layout = getCellLayout(container, screenId);                                          
1525                                                                                                          
1526         int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                      
1527         int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                            
1528                                                                                                          
1529         // Try finding open space on Launcher screen                                                     
1530         // We have saved the position to which the widget was dragged-- this really only matters         
1531         // if we are placing widgets on a "spring-loaded" screen                                         
1532         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1533         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1534         int[] finalSpan = new int[2];                                                                    
1535         boolean foundCellSpan = false;                                                                   
1536         if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                  
1537             cellXY[0] = mPendingAddInfo.cellX;                                                           
1538             cellXY[1] = mPendingAddInfo.cellY;                                                           
1539             spanXY[0] = mPendingAddInfo.spanX;                                                           
1540             spanXY[1] = mPendingAddInfo.spanY;                                                           
1541             foundCellSpan = true;                                                                        
1542         } else if (touchXY != null) {                                                                    
1543             // when dragging and dropping, just find the closest free spot                               
1544             int[] result = layout.findNearestVacantArea(                                                 
1545                     touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                       
1546                     spanXY[1], cellXY, finalSpan);                                                       
1547             spanXY[0] = finalSpan[0];                                                                    
1548             spanXY[1] = finalSpan[1];                                                                    
1549             foundCellSpan = (result != null);                                                            
1550         } else {                                                                                         
1551             foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                  
1552         }                                                                                                
1553                                                                                                          
1554         if (!foundCellSpan) {                                                                            
1555             if (appWidgetId != -1) {                                                                     
1556                 // Deleting an app widget ID is a void call but writes to disk before returning          
1557                 // to the caller...                                                                      
1558                 new AsyncTask<Void, Void, Void>() {                                                      
1559                     public Void doInBackground(Void ... args) {                                          
1560                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                   
1561                         return null;                                                                     
1562                     }                                                                                    
1563                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                        
1564             }                                                                                            
1565             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1566             return;                                                                                      
1567         }                                                                                                
1568                                                                                                          
1569         // Build Launcher-specific widget info and save to database                                      
1570         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                      
1571                 appWidgetInfo.provider);                                                                 
1572         launcherInfo.spanX = spanXY[0];                                                                  
1573         launcherInfo.spanY = spanXY[1];                                                                  
1574         launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                
1575         launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                
1576         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1577                                                                                                          
1578         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1579                 container, screenId, cellXY[0], cellXY[1], false);                                       
1580                                                                                                          
1581         if (!mRestoring) {                                                                               
1582             if (hostView == null) {                                                                      
1583                 // Perform actual inflation because we're live                                           
1584                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1585                 launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                          
1586             } else {                                                                                     
1587                 // The AppWidgetHostView has already been inflated and instantiated                      
1588                 launcherInfo.hostView = hostView;                                                        
1589             }                                                                                            
1590                                                                                                          
1591             launcherInfo.hostView.setTag(launcherInfo);                                                  
1592             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1593             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1594                                                                                                          
1595             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],     
1596                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                        
1597                                                                                                          
1598             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1599         }                                                                                                
1600         resetAddInfo();                                                                                  
1601     }                                                                                                    
1602                                                                                                          
1603     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1604         @Override                                                                                        
1605         public void onReceive(Context context, Intent intent) {                                          
1606             final String action = intent.getAction();                                                    
1607             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1608                 mUserPresent = false;                                                                    
1609                 mDragLayer.clearAllResizeFrames();                                                       
1610                 updateRunning();                                                                         
1611                                                                                                          
1612                 // Reset AllApps to its initial state only if we are not in the middle of                
1613                 // processing a multi-step drop                                                          
1614                 if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {      
1615                     showWorkspace(false);                                                                
1616                 }                                                                                        
1617             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1618                 mUserPresent = true;                                                                     
1619                 updateRunning();                                                                         
1620             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1621                 mModel.resetLoadedState(false, true);                                                    
1622                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1623                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1624             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1625                 mModel.resetLoadedState(false, true);                                                    
1626                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1627                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1628                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1629             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1630                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1631                 getModel().forceReload();                                                                
1632             }                                                                                            
1633         }                                                                                                
1634     };                                                                                                   
1635                                                                                                          
1636     @Override                                                                                            
1637     public void onAttachedToWindow() {                                                                   
1638         super.onAttachedToWindow();                                                                      
1639                                                                                                          
1640         // Listen for broadcasts related to user-presence                                                
1641         final IntentFilter filter = new IntentFilter();                                                  
1642         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1643         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1644         // For handling managed profiles                                                                 
1645         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1646         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1647         if (ENABLE_DEBUG_INTENTS) {                                                                      
1648             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1649             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1650         }                                                                                                
1651         registerReceiver(mReceiver, filter);                                                             
1652         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1653         setupTransparentSystemBarsForLmp();                                                              
1654         mAttached = true;                                                                                
1655         mVisible = true;                                                                                 
1656     }                                                                                                    
1657                                                                                                          
1658     /**                                                                                                  
1659      * Sets up transparent navigation and status bars in LMP.                                            
1660      * This method is a no-op for other platform versions.                                               
1661      */                                                                                                  
1662     @TargetApi(19)                                                                                       
1663     private void setupTransparentSystemBarsForLmp() {                                                    
1664         // TODO(sansid): use the APIs directly when compiling against L sdk.                             
1665         // Currently we use reflection to access the flags and the API to set the transparency           
1666         // on the System bars.                                                                           
1667         if (Utilities.isLmpOrAbove()) {                                                                  
1668             try {                                                                                        
1669                 getWindow().getAttributes().systemUiVisibility |=                                        
1670                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1671                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1672                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1673                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                
1674                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1675                 Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(              
1676                         "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                            
1677                 getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                             
1678                                                                                                          
1679                 Method setStatusBarColorMethod =                                                         
1680                         Window.class.getDeclaredMethod("setStatusBarColor", int.class);                  
1681                 Method setNavigationBarColorMethod =                                                     
1682                         Window.class.getDeclaredMethod("setNavigationBarColor", int.class);              
1683                 setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                          
1684                 setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                      
1685             } catch (NoSuchFieldException e) {                                                           
1686                 Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                    
1687             } catch (NoSuchMethodException ex) {                                                         
1688                 Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                   
1689             } catch (IllegalAccessException e) {                                                         
1690                 Log.w(TAG, "IllegalAccessException while setting up transparent bars");                  
1691             } catch (IllegalArgumentException e) {                                                       
1692                 Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                
1693             } catch (InvocationTargetException e) {                                                      
1694                 Log.w(TAG, "InvocationTargetException while setting up transparent bars");               
1695             } finally {}                                                                                 
1696         }                                                                                                
1697     }                                                                                                    
1698                                                                                                          
1699     @Override                                                                                            
1700     public void onDetachedFromWindow() {                                                                 
1701         super.onDetachedFromWindow();                                                                    
1702         mVisible = false;                                                                                
1703                                                                                                          
1704         if (mAttached) {                                                                                 
1705             unregisterReceiver(mReceiver);                                                               
1706             mAttached = false;                                                                           
1707         }                                                                                                
1708         updateRunning();                                                                                 
1709     }                                                                                                    
1710                                                                                                          
1711     public void onWindowVisibilityChanged(int visibility) {                                              
1712         mVisible = visibility == View.VISIBLE;                                                           
1713         updateRunning();                                                                                 
1714         // The following code used to be in onResume, but it turns out onResume is called when           
1715         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1716         // is a more appropriate event to handle                                                         
1717         if (mVisible) {                                                                                  
1718             mAppsCustomizeTabHost.onWindowVisible();                                                     
1719             if (!mWorkspaceLoading) {                                                                    
1720                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1721                 // We want to let Launcher draw itself at least once before we force it to build         
1722                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1723                 // apps is nice and speedy.                                                              
1724                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1725                     private boolean mStarted = false;                                                    
1726                     public void onDraw() {                                                               
1727                         if (mStarted) return;                                                            
1728                         mStarted = true;                                                                 
1729                         // We delay the layer building a bit in order to give                            
1730                         // other message processing a time to run.  In particular                        
1731                         // this avoids a delay in hiding the IME if it was                               
1732                         // currently shown, because doing that may involve                               
1733                         // some communication back with the app.                                         
1734                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1735                         final ViewTreeObserver.OnDrawListener listener = this;                           
1736                         mWorkspace.post(new Runnable() {                                                 
1737                                 public void run() {                                                      
1738                                     if (mWorkspace != null &&                                            
1739                                             mWorkspace.getViewTreeObserver() != null) {                  
1740                                         mWorkspace.getViewTreeObserver().                                
1741                                                 removeOnDrawListener(listener);                          
1742                                     }                                                                    
1743                                 }                                                                        
1744                             });                                                                          
1745                         return;                                                                          
1746                     }                                                                                    
1747                 });                                                                                      
1748             }                                                                                            
1749             clearTypedText();                                                                            
1750         }                                                                                                
1751     }                                                                                                    
1752                                                                                                          
1753     private void sendAdvanceMessage(long delay) {                                                        
1754         mHandler.removeMessages(ADVANCE_MSG);                                                            
1755         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1756         mHandler.sendMessageDelayed(msg, delay);                                                         
1757         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1758     }                                                                                                    
1759                                                                                                          
1760     private void updateRunning() {                                                                       
1761         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1762         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1763             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1764             if (autoAdvanceRunning) {                                                                    
1765                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1766                 sendAdvanceMessage(delay);                                                               
1767             } else {                                                                                     
1768                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1769                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1770                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1771                 }                                                                                        
1772                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1773                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1774             }                                                                                            
1775         }                                                                                                
1776     }                                                                                                    
1777                                                                                                          
1778     private final Handler mHandler = new Handler() {                                                     
1779         @Override                                                                                        
1780         public void handleMessage(Message msg) {                                                         
1781             if (msg.what == ADVANCE_MSG) {                                                               
1782                 int i = 0;                                                                               
1783                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1784                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1785                     final int delay = mAdvanceStagger * i;                                               
1786                     if (v instanceof Advanceable) {                                                      
1787                        postDelayed(new Runnable() {                                                      
1788                            public void run() {                                                           
1789                                ((Advanceable) v).advance();                                              
1790                            }                                                                             
1791                        }, delay);                                                                        
1792                     }                                                                                    
1793                     i++;                                                                                 
1794                 }                                                                                        
1795                 sendAdvanceMessage(mAdvanceInterval);                                                    
1796             }                                                                                            
1797         }                                                                                                
1798     };                                                                                                   
1799                                                                                                          
1800     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1801         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1802         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1803         if (v instanceof Advanceable) {                                                                  
1804             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1805             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1806             updateRunning();                                                                             
1807         }                                                                                                
1808     }                                                                                                    
1809                                                                                                          
1810     void removeWidgetToAutoAdvance(View hostView) {                                                      
1811         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1812             mWidgetsToAdvance.remove(hostView);                                                          
1813             updateRunning();                                                                             
1814         }                                                                                                
1815     }                                                                                                    
1816                                                                                                          
1817     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1818         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1819         launcherInfo.hostView = null;                                                                    
1820     }                                                                                                    
1821                                                                                                          
1822     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1823         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1824         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1825     }                                                                                                    
1826                                                                                                          
1827     public DragLayer getDragLayer() {                                                                    
1828         return mDragLayer;                                                                               
1829     }                                                                                                    
1830                                                                                                          
1831     public Workspace getWorkspace() {                                                                    
1832         return mWorkspace;                                                                               
1833     }                                                                                                    
1834                                                                                                          
1835     public Hotseat getHotseat() {                                                                        
1836         return mHotseat;                                                                                 
1837     }                                                                                                    
1838                                                                                                          
1839     public ViewGroup getOverviewPanel() {                                                                
1840         return mOverviewPanel;                                                                           
1841     }                                                                                                    
1842                                                                                                          
1843     public SearchDropTargetBar getSearchBar() {                                                          
1844         return mSearchDropTargetBar;                                                                     
1845     }                                                                                                    
1846                                                                                                          
1847     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1848         return mAppWidgetHost;                                                                           
1849     }                                                                                                    
1850                                                                                                          
1851     public LauncherModel getModel() {                                                                    
1852         return mModel;                                                                                   
1853     }                                                                                                    
1854                                                                                                          
1855     protected SharedPreferences getSharedPrefs() {                                                       
1856         return mSharedPrefs;                                                                             
1857     }                                                                                                    
1858                                                                                                          
1859     public void closeSystemDialogs() {                                                                   
1860         getWindow().closeAllPanels();                                                                    
1861                                                                                                          
1862         // Whatever we were doing is hereby canceled.                                                    
1863         setWaitingForResult(false);                                                                      
1864     }                                                                                                    
1865                                                                                                          
1866     @Override                                                                                            
1867     protected void onNewIntent(Intent intent) {                                                          
1868         long startTime = 0;                                                                              
1869         if (DEBUG_RESUME_TIME) {                                                                         
1870             startTime = System.currentTimeMillis();                                                      
1871         }                                                                                                
1872         super.onNewIntent(intent);                                                                       
1873                                                                                                          
1874         // Close the menu                                                                                
1875         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1876             // also will cancel mWaitingForResult.                                                       
1877             closeSystemDialogs();                                                                        
1878                                                                                                          
1879             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1880                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1881                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1882                                                                                                          
1883             if (mWorkspace == null) {                                                                    
1884                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1885                 return;                                                                                  
1886             }                                                                                            
1887             Folder openFolder = mWorkspace.getOpenFolder();                                              
1888             // In all these cases, only animate if we're already on home                                 
1889             mWorkspace.exitWidgetResizeMode();                                                           
1890             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1891                     openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                     
1892                 mWorkspace.moveToDefaultScreen(true);                                                    
1893             }                                                                                            
1894                                                                                                          
1895             closeFolder();                                                                               
1896             exitSpringLoadedDragMode();                                                                  
1897                                                                                                          
1898             // If we are already on home, then just animate back to the workspace,                       
1899             // otherwise, just wait until onResume to set the state back to Workspace                    
1900             if (alreadyOnHome) {                                                                         
1901                 showWorkspace(true);                                                                     
1902             } else {                                                                                     
1903                 mOnResumeState = State.WORKSPACE;                                                        
1904             }                                                                                            
1905                                                                                                          
1906             final View v = getWindow().peekDecorView();                                                  
1907             if (v != null && v.getWindowToken() != null) {                                               
1908                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1909                         INPUT_METHOD_SERVICE);                                                           
1910                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1911             }                                                                                            
1912                                                                                                          
1913             // Reset the apps customize page                                                             
1914             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1915                 mAppsCustomizeTabHost.reset();                                                           
1916             }                                                                                            
1917                                                                                                          
1918             onHomeIntent();                                                                              
1919         }                                                                                                
1920                                                                                                          
1921         if (DEBUG_RESUME_TIME) {                                                                         
1922             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1923         }                                                                                                
1924     }                                                                                                    
1925                                                                                                          
1926     /**                                                                                                  
1927      * Override point for subclasses to prevent movement to the default screen when the home             
1928      * button is pressed. Used (for example) in GEL, to prevent movement during a search.                
1929      */                                                                                                  
1930     protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                          
1931         return true;                                                                                     
1932     }                                                                                                    
1933                                                                                                          
1934     /**                                                                                                  
1935      * Override point for subclasses to provide custom behaviour for when a home intent is fired.        
1936      */                                                                                                  
1937     protected void onHomeIntent() {                                                                      
1938         // Do nothing                                                                                    
1939     }                                                                                                    
1940                                                                                                          
1941     @Override                                                                                            
1942     public void onRestoreInstanceState(Bundle state) {                                                   
1943         super.onRestoreInstanceState(state);                                                             
1944         for (int page: mSynchronouslyBoundPages) {                                                       
1945             mWorkspace.restoreInstanceStateForChild(page);                                               
1946         }                                                                                                
1947     }                                                                                                    
1948                                                                                                          
1949     @Override                                                                                            
1950     protected void onSaveInstanceState(Bundle outState) {                                                
1951         if (mWorkspace.getChildCount() > 0) {                                                            
1952             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1953                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1954         }                                                                                                
1955         super.onSaveInstanceState(outState);                                                             
1956                                                                                                          
1957         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1958         // We close any open folder since it will not be re-opened, and we need to make sure             
1959         // this state is reflected.                                                                      
1960         closeFolder();                                                                                   
1961                                                                                                          
1962         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1963                 mWaitingForResult) {                                                                     
1964             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1965             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1966             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1967             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1968             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1969             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1970             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1971             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1972         }                                                                                                
1973                                                                                                          
1974         if (mFolderInfo != null && mWaitingForResult) {                                                  
1975             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
1976             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
1977         }                                                                                                
1978                                                                                                          
1979         // Save the current AppsCustomize tab                                                            
1980         if (mAppsCustomizeTabHost != null) {                                                             
1981             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
1982             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
1983             if (currentTabTag != null) {                                                                 
1984                 outState.putString("apps_customize_currentTab", currentTabTag);                          
1985             }                                                                                            
1986             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
1987             outState.putInt("apps_customize_currentIndex", currentIndex);                                
1988         }                                                                                                
1989         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1990     }                                                                                                    
1991                                                                                                          
1992     @Override                                                                                            
1993     public void onDestroy() {                                                                            
1994         super.onDestroy();                                                                               
1995                                                                                                          
1996         // Remove all pending runnables                                                                  
1997         mHandler.removeMessages(ADVANCE_MSG);                                                            
1998         mHandler.removeMessages(0);                                                                      
1999         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2000                                                                                                          
2001         // Stop callbacks from LauncherModel                                                             
2002         LauncherAppState app = (LauncherAppState.getInstance());                                         
2003                                                                                                          
2004         // It's possible to receive onDestroy after a new Launcher activity has                          
2005         // been created. In this case, don't interfere with the new Launcher.                            
2006         if (mModel.isCurrentCallbacks(this)) {                                                           
2007             mModel.stopLoader();                                                                         
2008             app.setLauncher(null);                                                                       
2009         }                                                                                                
2010                                                                                                          
2011         try {                                                                                            
2012             mAppWidgetHost.stopListening();                                                              
2013         } catch (NullPointerException ex) {                                                              
2014             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2015         }                                                                                                
2016         mAppWidgetHost = null;                                                                           
2017                                                                                                          
2018         mWidgetsToAdvance.clear();                                                                       
2019                                                                                                          
2020         TextKeyListener.getInstance().release();                                                         
2021                                                                                                          
2022         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2023         // to prevent leaking Launcher activities on orientation change.                                 
2024         if (mModel != null) {                                                                            
2025             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2026         }                                                                                                
2027                                                                                                          
2028         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2029         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2030                                                                                                          
2031         mDragLayer.clearAllResizeFrames();                                                               
2032         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2033         mWorkspace.removeAllWorkspaceScreens();                                                          
2034         mWorkspace = null;                                                                               
2035         mDragController = null;                                                                          
2036                                                                                                          
2037         PackageInstallerCompat.getInstance(this).onStop();                                               
2038         LauncherAnimUtils.onDestroyActivity();                                                           
2039     }                                                                                                    
2040                                                                                                          
2041     public DragController getDragController() {                                                          
2042         return mDragController;                                                                          
2043     }                                                                                                    
2044                                                                                                          
2045     @Override                                                                                            
2046     public void startActivityForResult(Intent intent, int requestCode) {                                 
2047         if (requestCode >= 0) {                                                                          
2048             setWaitingForResult(true);                                                                   
2049         }                                                                                                
2050         super.startActivityForResult(intent, requestCode);                                               
2051     }                                                                                                    
2052                                                                                                          
2053     /**                                                                                                  
2054      * Indicates that we want global search for this activity by setting the globalSearch                
2055      * argument for {@link #startSearch} to true.                                                        
2056      */                                                                                                  
2057     @Override                                                                                            
2058     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2059             Bundle appSearchData, boolean globalSearch) {                                                
2060                                                                                                          
2061         showWorkspace(true);                                                                             
2062                                                                                                          
2063         if (initialQuery == null) {                                                                      
2064             // Use any text typed in the launcher as the initial query                                   
2065             initialQuery = getTypedText();                                                               
2066         }                                                                                                
2067         if (appSearchData == null) {                                                                     
2068             appSearchData = new Bundle();                                                                
2069             appSearchData.putString("source", "launcher-search");                                        
2070         }                                                                                                
2071         Rect sourceBounds = new Rect();                                                                  
2072         if (mSearchDropTargetBar != null) {                                                              
2073             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2074         }                                                                                                
2075                                                                                                          
2076         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2077                 appSearchData, sourceBounds);                                                            
2078         if (clearTextImmediately) {                                                                      
2079             clearTypedText();                                                                            
2080         }                                                                                                
2081     }                                                                                                    
2082                                                                                                          
2083     /**                                                                                                  
2084      * Start a text search.                                                                              
2085      *                                                                                                   
2086      * @return {@code true} if the search will start immediately, so any further keypresses              
2087      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2088      * to buffer keypresses.                                                                             
2089      */                                                                                                  
2090     public boolean startSearch(String initialQuery,                                                      
2091             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2092         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2093                 appSearchData, sourceBounds);                                                            
2094         return false;                                                                                    
2095     }                                                                                                    
2096                                                                                                          
2097     /**                                                                                                  
2098      * Starts the global search activity. This code is a copied from SearchManager                       
2099      */                                                                                                  
2100     private void startGlobalSearch(String initialQuery,                                                  
2101             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2102         final SearchManager searchManager =                                                              
2103             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2104         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2105         if (globalSearchActivity == null) {                                                              
2106             Log.w(TAG, "No global search activity found.");                                              
2107             return;                                                                                      
2108         }                                                                                                
2109         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2110         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2111         intent.setComponent(globalSearchActivity);                                                       
2112         // Make sure that we have a Bundle to put source in                                              
2113         if (appSearchData == null) {                                                                     
2114             appSearchData = new Bundle();                                                                
2115         } else {                                                                                         
2116             appSearchData = new Bundle(appSearchData);                                                   
2117         }                                                                                                
2118         // Set source to package name of app that starts global search, if not set already.              
2119         if (!appSearchData.containsKey("source")) {                                                      
2120             appSearchData.putString("source", getPackageName());                                         
2121         }                                                                                                
2122         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2123         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2124             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2125         }                                                                                                
2126         if (selectInitialQuery) {                                                                        
2127             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2128         }                                                                                                
2129         intent.setSourceBounds(sourceBounds);                                                            
2130         try {                                                                                            
2131             startActivity(intent);                                                                       
2132         } catch (ActivityNotFoundException ex) {                                                         
2133             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2134         }                                                                                                
2135     }                                                                                                    
2136                                                                                                          
2137     public boolean isOnCustomContent() {                                                                 
2138         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2139     }                                                                                                    
2140                                                                                                          
2141     @Override                                                                                            
2142     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2143         super.onPrepareOptionsMenu(menu);                                                                
2144         if (!isOnCustomContent()) {                                                                      
2145             // Close any open folders                                                                    
2146             closeFolder();                                                                               
2147             // Stop resizing any widgets                                                                 
2148             mWorkspace.exitWidgetResizeMode();                                                           
2149             if (!mWorkspace.isInOverviewMode()) {                                                        
2150                 // Show the overview mode                                                                
2151                 showOverviewMode(true);                                                                  
2152             } else {                                                                                     
2153                 showWorkspace(true);                                                                     
2154             }                                                                                            
2155         }                                                                                                
2156         return false;                                                                                    
2157     }                                                                                                    
2158                                                                                                          
2159     @Override                                                                                            
2160     public boolean onSearchRequested() {                                                                 
2161         startSearch(null, false, null, true);                                                            
2162         // Use a custom animation for launching search                                                   
2163         return true;                                                                                     
2164     }                                                                                                    
2165                                                                                                          
2166     public boolean isWorkspaceLocked() {                                                                 
2167         return mWorkspaceLoading || mWaitingForResult;                                                   
2168     }                                                                                                    
2169                                                                                                          
2170 <<<<<<< GitAnalyzerPlus_ours                                                                             
2171     public boolean isWorkspaceLoading() {                                                                
2172         return mWorkspaceLoading;                                                                        
2173     }                                                                                                    
2174                                                                                                          
2175     private void setWorkspaceLoading(boolean value) {                                                    
2176         boolean isLocked = isWorkspaceLocked();                                                          
2177         mWorkspaceLoading = value;                                                                       
2178         if (isLocked != isWorkspaceLocked()) {                                                           
2179             onWorkspaceLockedChanged();                                                                  
2180         }                                                                                                
2181     }                                                                                                    
2182                                                                                                          
2183     private void setWaitingForResult(boolean value) {                                                    
2184         boolean isLocked = isWorkspaceLocked();                                                          
2185         mWaitingForResult = value;                                                                       
2186         if (isLocked != isWorkspaceLocked()) {                                                           
2187             onWorkspaceLockedChanged();                                                                  
2188         }                                                                                                
2189     }                                                                                                    
2190                                                                                                          
2191     protected void onWorkspaceLockedChanged() { }                                                        
2192                                                                                                          
2193 ||||||| GitAnalyzerPlus_base                                                                             
2194     public boolean isWorkspaceLoading() {                                                                
2195         return mWorkspaceLoading;                                                                        
2196     }                                                                                                    
2197                                                                                                          
2198     private void resetAddInfo() {                                                                        
2199         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2200         mPendingAddInfo.screenId = -1;                                                                   
2201         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2202         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2203         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2204         mPendingAddInfo.dropPos = null;                                                                  
2205     }                                                                                                    
2206                                                                                                          
2207     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2208             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2209         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2210     }                                                                                                    
2211                                                                                                          
2212     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2213             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int          
2214             delay) {                                                                                     
2215         if (appWidgetInfo.configure != null) {                                                           
2216             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2217             mPendingAddWidgetId = appWidgetId;                                                           
2218                                                                                                          
2219             // Launch over to configure widget, if needed                                                
2220             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);                     
2221             intent.setComponent(appWidgetInfo.configure);                                                
2222             intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                           
2223             Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_APPWIDGET);              
2224         } else {                                                                                         
2225             // Otherwise just add it                                                                     
2226             Runnable onComplete = new Runnable() {                                                       
2227                 @Override                                                                                
2228                 public void run() {                                                                      
2229                     // Exit spring loaded mode if necessary after adding the widget                      
2230                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2231                             null);                                                                       
2232                 }                                                                                        
2233             };                                                                                           
2234             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2235                     appWidgetInfo);                                                                      
2236             mWorkspace.removeExtraEmptyScreen(true, onComplete, delay, false);                           
2237         }                                                                                                
2238     }                                                                                                    
2239                                                                                                          
2240     protected void moveToCustomContentScreen(boolean animate) {                                          
2241         // Close any folders that may be open.                                                           
2242         closeFolder();                                                                                   
2243         mWorkspace.moveToCustomContentScreen(animate);                                                   
2244     }                                                                                                    
2245     /**                                                                                                  
2246      * Process a shortcut drop.                                                                          
2247      *                                                                                                   
2248      * @param componentName The name of the component                                                    
2249      * @param screenId The ID of the screen where it should be added                                     
2250      * @param cell The cell it should be added to, optional                                              
2251      * @param position The location on the screen where it was dropped, optional                         
2252      */                                                                                                  
2253     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2254             int[] cell, int[] loc) {                                                                     
2255         resetAddInfo();                                                                                  
2256         mPendingAddInfo.container = container;                                                           
2257         mPendingAddInfo.screenId = screenId;                                                             
2258         mPendingAddInfo.dropPos = loc;                                                                   
2259                                                                                                          
2260         if (cell != null) {                                                                              
2261             mPendingAddInfo.cellX = cell[0];                                                             
2262             mPendingAddInfo.cellY = cell[1];                                                             
2263         }                                                                                                
2264                                                                                                          
2265         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2266         createShortcutIntent.setComponent(componentName);                                                
2267         processShortcut(createShortcutIntent);                                                           
2268     }                                                                                                    
2269                                                                                                          
2270     /**                                                                                                  
2271      * Process a widget drop.                                                                            
2272      *                                                                                                   
2273      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2274      * @param screenId The ID of the screen where it should be added                                     
2275      * @param cell The cell it should be added to, optional                                              
2276      * @param position The location on the screen where it was dropped, optional                         
2277      */                                                                                                  
2278     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                  
2279             int[] cell, int[] span, int[] loc) {                                                         
2280         resetAddInfo();                                                                                  
2281         mPendingAddInfo.container = info.container = container;                                          
2282         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2283         mPendingAddInfo.dropPos = loc;                                                                   
2284         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2285         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2286                                                                                                          
2287         if (cell != null) {                                                                              
2288             mPendingAddInfo.cellX = cell[0];                                                             
2289             mPendingAddInfo.cellY = cell[1];                                                             
2290         }                                                                                                
2291         if (span != null) {                                                                              
2292             mPendingAddInfo.spanX = span[0];                                                             
2293             mPendingAddInfo.spanY = span[1];                                                             
2294         }                                                                                                
2295                                                                                                          
2296         AppWidgetHostView hostView = info.boundWidget;                                                   
2297         int appWidgetId;                                                                                 
2298         if (hostView != null) {                                                                          
2299             appWidgetId = hostView.getAppWidgetId();                                                     
2300             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2301         } else {                                                                                         
2302             // In this case, we either need to start an activity to get permission to bind               
2303             // the widget, or we need to start an activity to configure the widget, or both.             
2304             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2305 =======                                                                                                  
2306 >>>>>>> GitAnalyzerPlus_theirs                                                                           
2307     private void resetAddInfo() {                                                                        
2308         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2309         mPendingAddInfo.screenId = -1;                                                                   
2310         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2311         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2312         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2313         mPendingAddInfo.dropPos = null;                                                                  
2314     }                                                                                                    
2315                                                                                                          
2316     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2317             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2318         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2319     }                                                                                                    
2320                                                                                                          
2321     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2322             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int          
2323             delay) {                                                                                     
2324         if (appWidgetInfo.configure != null) {                                                           
2325             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2326             mPendingAddWidgetId = appWidgetId;                                                           
2327                                                                                                          
2328             // Launch over to configure widget, if needed                                                
2329             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2330                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2331                                                                                                          
2332         } else {                                                                                         
2333             // Otherwise just add it                                                                     
2334             Runnable onComplete = new Runnable() {                                                       
2335                 @Override                                                                                
2336                 public void run() {                                                                      
2337                     // Exit spring loaded mode if necessary after adding the widget                      
2338                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2339                             null);                                                                       
2340                 }                                                                                        
2341             };                                                                                           
2342             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2343                     appWidgetInfo);                                                                      
2344             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2345         }                                                                                                
2346     }                                                                                                    
2347                                                                                                          
2348     protected void moveToCustomContentScreen(boolean animate) {                                          
2349         // Close any folders that may be open.                                                           
2350         closeFolder();                                                                                   
2351         mWorkspace.moveToCustomContentScreen(animate);                                                   
2352     }                                                                                                    
2353     /**                                                                                                  
2354      * Process a shortcut drop.                                                                          
2355      *                                                                                                   
2356      * @param componentName The name of the component                                                    
2357      * @param screenId The ID of the screen where it should be added                                     
2358      * @param cell The cell it should be added to, optional                                              
2359      * @param position The location on the screen where it was dropped, optional                         
2360      */                                                                                                  
2361     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2362             int[] cell, int[] loc) {                                                                     
2363         resetAddInfo();                                                                                  
2364         mPendingAddInfo.container = container;                                                           
2365         mPendingAddInfo.screenId = screenId;                                                             
2366         mPendingAddInfo.dropPos = loc;                                                                   
2367                                                                                                          
2368         if (cell != null) {                                                                              
2369             mPendingAddInfo.cellX = cell[0];                                                             
2370             mPendingAddInfo.cellY = cell[1];                                                             
2371         }                                                                                                
2372                                                                                                          
2373         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2374         createShortcutIntent.setComponent(componentName);                                                
2375         processShortcut(createShortcutIntent);                                                           
2376     }                                                                                                    
2377                                                                                                          
2378     /**                                                                                                  
2379      * Process a widget drop.                                                                            
2380      *                                                                                                   
2381      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2382      * @param screenId The ID of the screen where it should be added                                     
2383      * @param cell The cell it should be added to, optional                                              
2384      * @param position The location on the screen where it was dropped, optional                         
2385      */                                                                                                  
2386     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                  
2387             int[] cell, int[] span, int[] loc) {                                                         
2388         resetAddInfo();                                                                                  
2389         mPendingAddInfo.container = info.container = container;                                          
2390         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2391         mPendingAddInfo.dropPos = loc;                                                                   
2392         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2393         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2394                                                                                                          
2395         if (cell != null) {                                                                              
2396             mPendingAddInfo.cellX = cell[0];                                                             
2397             mPendingAddInfo.cellY = cell[1];                                                             
2398         }                                                                                                
2399         if (span != null) {                                                                              
2400             mPendingAddInfo.spanX = span[0];                                                             
2401             mPendingAddInfo.spanY = span[1];                                                             
2402         }                                                                                                
2403                                                                                                          
2404         AppWidgetHostView hostView = info.boundWidget;                                                   
2405         int appWidgetId;                                                                                 
2406         if (hostView != null) {                                                                          
2407             appWidgetId = hostView.getAppWidgetId();                                                     
2408             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2409         } else {                                                                                         
2410             // In this case, we either need to start an activity to get permission to bind               
2411             // the widget, or we need to start an activity to configure the widget, or both.             
2412             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2413             Bundle options = info.bindOptions;                                                           
2414                                                                                                          
2415             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2416                     appWidgetId, info.info, options);                                                    
2417             if (success) {                                                                               
2418                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2419             } else {                                                                                     
2420                 mPendingAddWidgetInfo = info.info;                                                       
2421                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2422                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2423                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2424                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2425                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2426                 // TODO: we need to make sure that this accounts for the options bundle.                 
2427                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2428                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2429             }                                                                                            
2430         }                                                                                                
2431     }                                                                                                    
2432                                                                                                          
2433     void processShortcut(Intent intent) {                                                                
2434         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2435     }                                                                                                    
2436                                                                                                          
2437     void processWallpaper(Intent intent) {                                                               
2438         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2439     }                                                                                                    
2440                                                                                                          
2441     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2442             int cellY) {                                                                                 
2443         final FolderInfo folderInfo = new FolderInfo();                                                  
2444         folderInfo.title = getText(R.string.folder_name);                                                
2445                                                                                                          
2446         // Update the model                                                                              
2447         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2448                 false);                                                                                  
2449         sFolders.put(folderInfo.id, folderInfo);                                                         
2450                                                                                                          
2451         // Create the view                                                                               
2452         FolderIcon newFolder =                                                                           
2453             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2454         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2455                 isWorkspaceLocked());                                                                    
2456         // Force measure the new folder icon                                                             
2457         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2458         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2459         return newFolder;                                                                                
2460     }                                                                                                    
2461                                                                                                          
2462     void removeFolder(FolderInfo folder) {                                                               
2463         sFolders.remove(folder.id);                                                                      
2464     }                                                                                                    
2465                                                                                                          
2466     protected ComponentName getWallpaperPickerComponent() {                                              
2467         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2468     }                                                                                                    
2469                                                                                                          
2470     /**                                                                                                  
2471      * Registers various content observers. The current implementation registers                         
2472      * only a favorites observer to keep track of the favorites applications.                            
2473      */                                                                                                  
2474     private void registerContentObservers() {                                                            
2475         ContentResolver resolver = getContentResolver();                                                 
2476         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2477                 true, mWidgetObserver);                                                                  
2478     }                                                                                                    
2479                                                                                                          
2480     @Override                                                                                            
2481     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2482         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2483             switch (event.getKeyCode()) {                                                                
2484                 case KeyEvent.KEYCODE_HOME:                                                              
2485                     return true;                                                                         
2486                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2487                     if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                        
2488                         dumpState();                                                                     
2489                         return true;                                                                     
2490                     }                                                                                    
2491                     break;                                                                               
2492             }                                                                                            
2493         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2494             switch (event.getKeyCode()) {                                                                
2495                 case KeyEvent.KEYCODE_HOME:                                                              
2496                     return true;                                                                         
2497             }                                                                                            
2498         }                                                                                                
2499                                                                                                          
2500         return super.dispatchKeyEvent(event);                                                            
2501     }                                                                                                    
2502                                                                                                          
2503     @Override                                                                                            
2504     public void onBackPressed() {                                                                        
2505         if (isAllAppsVisible()) {                                                                        
2506             if (mAppsCustomizeContent.getContentType() ==                                                
2507                     AppsCustomizePagedView.ContentType.Applications) {                                   
2508                 showWorkspace(true);                                                                     
2509             } else {                                                                                     
2510                 showOverviewMode(true);                                                                  
2511             }                                                                                            
2512         } else if (mWorkspace.isInOverviewMode()) {                                                      
2513             mWorkspace.exitOverviewMode(true);                                                           
2514         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2515             Folder openFolder = mWorkspace.getOpenFolder();                                              
2516             if (openFolder.isEditingName()) {                                                            
2517                 openFolder.dismissEditingName();                                                         
2518             } else {                                                                                     
2519                 closeFolder();                                                                           
2520             }                                                                                            
2521         } else {                                                                                         
2522             mWorkspace.exitWidgetResizeMode();                                                           
2523                                                                                                          
2524             // Back button is a no-op here, but give at least some feedback for the button press         
2525             mWorkspace.showOutlinesTemporarily();                                                        
2526         }                                                                                                
2527     }                                                                                                    
2528                                                                                                          
2529     /**                                                                                                  
2530      * Re-listen when widgets are reset.                                                                 
2531      */                                                                                                  
2532     private void onAppWidgetReset() {                                                                    
2533         if (mAppWidgetHost != null) {                                                                    
2534             mAppWidgetHost.startListening();                                                             
2535         }                                                                                                
2536     }                                                                                                    
2537                                                                                                          
2538     /**                                                                                                  
2539      * Launches the intent referred by the clicked shortcut.                                             
2540      *                                                                                                   
2541      * @param v The view representing the clicked shortcut.                                              
2542      */                                                                                                  
2543     public void onClick(View v) {                                                                        
2544         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2545         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2546         if (v.getWindowToken() == null) {                                                                
2547             return;                                                                                      
2548         }                                                                                                
2549                                                                                                          
2550         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2551             return;                                                                                      
2552         }                                                                                                
2553                                                                                                          
2554         if (v instanceof Workspace) {                                                                    
2555             if (mWorkspace.isInOverviewMode()) {                                                         
2556                 mWorkspace.exitOverviewMode(true);                                                       
2557             }                                                                                            
2558             return;                                                                                      
2559         }                                                                                                
2560                                                                                                          
2561         if (v instanceof CellLayout) {                                                                   
2562             if (mWorkspace.isInOverviewMode()) {                                                         
2563                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2564             }                                                                                            
2565         }                                                                                                
2566                                                                                                          
2567         Object tag = v.getTag();                                                                         
2568         if (tag instanceof ShortcutInfo) {                                                               
2569             onClickAppShortcut(v);                                                                       
2570         } else if (tag instanceof FolderInfo) {                                                          
2571             if (v instanceof FolderIcon) {                                                               
2572                 onClickFolderIcon(v);                                                                    
2573             }                                                                                            
2574         } else if (v == mAllAppsButton) {                                                                
2575             onClickAllAppsButton(v);                                                                     
2576         } else if (tag instanceof AppInfo) {                                                             
2577             startAppShortcutOrInfoActivity(v);                                                           
2578         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2579             if (v instanceof PendingAppWidgetHostView) {                                                 
2580                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2581             }                                                                                            
2582         }                                                                                                
2583     }                                                                                                    
2584                                                                                                          
2585     public void onClickPagedViewIcon(View v) {                                                           
2586         startAppShortcutOrInfoActivity(v);                                                               
2587     }                                                                                                    
2588                                                                                                          
2589     public boolean onTouch(View v, MotionEvent event) {                                                  
2590         return false;                                                                                    
2591     }                                                                                                    
2592                                                                                                          
2593     /**                                                                                                  
2594      * Event handler for the app widget view which has not fully restored.                               
2595      */                                                                                                  
2596     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2597         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2598         if (v.isReadyForClickSetup()) {                                                                  
2599             int widgetId = info.appWidgetId;                                                             
2600             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2601             if (appWidgetInfo != null) {                                                                 
2602                 mPendingAddWidgetInfo = appWidgetInfo;                                                   
2603                 mPendingAddInfo.copyFrom(info);                                                          
2604                 mPendingAddWidgetId = widgetId;                                                          
2605                                                                                                          
2606                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2607                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2608             }                                                                                            
2609         } else if (info.installProgress < 0) {                                                           
2610             // The install has not been queued                                                           
2611             final String packageName = info.providerName.getPackageName();                               
2612             showBrokenAppInstallDialog(packageName,                                                      
2613                 new DialogInterface.OnClickListener() {                                                  
2614                     public void onClick(DialogInterface dialog, int id) {                                
2615                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2616                     }                                                                                    
2617                 });                                                                                      
2618         } else {                                                                                         
2619             // Download has started.                                                                     
2620             final String packageName = info.providerName.getPackageName();                               
2621             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2622         }                                                                                                
2623     }                                                                                                    
2624                                                                                                          
2625     /**                                                                                                  
2626      * Event handler for the search button                                                               
2627      *                                                                                                   
2628      * @param v The view that was clicked.                                                               
2629      */                                                                                                  
2630     public void onClickSearchButton(View v) {                                                            
2631         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2632                                                                                                          
2633         onSearchRequested();                                                                             
2634     }                                                                                                    
2635                                                                                                          
2636     /**                                                                                                  
2637      * Event handler for the voice button                                                                
2638      *                                                                                                   
2639      * @param v The view that was clicked.                                                               
2640      */                                                                                                  
2641     public void onClickVoiceButton(View v) {                                                             
2642         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2643                                                                                                          
2644         startVoice();                                                                                    
2645     }                                                                                                    
2646                                                                                                          
2647     public void startVoice() {                                                                           
2648         try {                                                                                            
2649             final SearchManager searchManager =                                                          
2650                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);                            
2651             ComponentName activityName = searchManager.getGlobalSearchActivity();                        
2652             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2653             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2654             if (activityName != null) {                                                                  
2655                 intent.setPackage(activityName.getPackageName());                                        
2656             }                                                                                            
2657             startActivity(null, intent, "onClickVoiceButton");                                           
2658         } catch (ActivityNotFoundException e) {                                                          
2659             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2660             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2661             startActivitySafely(null, intent, "onClickVoiceButton");                                     
2662         }                                                                                                
2663     }                                                                                                    
2664                                                                                                          
2665     /**                                                                                                  
2666      * Event handler for the "grid" button that appears on the home screen, which                        
2667      * enters all apps mode.                                                                             
2668      *                                                                                                   
2669      * @param v The view that was clicked.                                                               
2670      */                                                                                                  
2671     protected void onClickAllAppsButton(View v) {                                                        
2672         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2673         if (isAllAppsVisible()) {                                                                        
2674             showWorkspace(true);                                                                         
2675         } else {                                                                                         
2676             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                   
2677         }                                                                                                
2678     }                                                                                                    
2679                                                                                                          
2680     private void showBrokenAppInstallDialog(final String packageName,                                    
2681             DialogInterface.OnClickListener onSearchClickListener) {                                     
2682         new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))      
2683             .setTitle(R.string.abandoned_promises_title)                                                 
2684             .setMessage(R.string.abandoned_promise_explanation)                                          
2685             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2686             .setNeutralButton(R.string.abandoned_clean_this,                                             
2687                 new DialogInterface.OnClickListener() {                                                  
2688                     public void onClick(DialogInterface dialog, int id) {                                
2689                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2690                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2691                     }                                                                                    
2692                 })                                                                                       
2693             .create().show();                                                                            
2694         return;                                                                                          
2695     }                                                                                                    
2696                                                                                                          
2697     /**                                                                                                  
2698      * Event handler for an app shortcut click.                                                          
2699      *                                                                                                   
2700      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2701      */                                                                                                  
2702     protected void onClickAppShortcut(final View v) {                                                    
2703         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2704         Object tag = v.getTag();                                                                         
2705         if (!(tag instanceof ShortcutInfo)) {                                                            
2706             throw new IllegalArgumentException("Input must be a Shortcut");                              
2707         }                                                                                                
2708                                                                                                          
2709         // Open shortcut                                                                                 
2710         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2711         final Intent intent = shortcut.intent;                                                           
2712                                                                                                          
2713         // Check for special shortcuts                                                                   
2714         if (intent.getComponent() != null) {                                                             
2715             final String shortcutClass = intent.getComponent().getClassName();                           
2716                                                                                                          
2717             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2718                 MemoryDumpActivity.startDump(this);                                                      
2719                 return;                                                                                  
2720             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2721                 toggleShowWeightWatcher();                                                               
2722                 return;                                                                                  
2723             }                                                                                            
2724         }                                                                                                
2725                                                                                                          
2726         // Check for abandoned promise                                                                   
2727         if ((v instanceof BubbleTextView)                                                                
2728                 && shortcut.isPromise()                                                                  
2729                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2730             showBrokenAppInstallDialog(                                                                  
2731                     shortcut.getTargetComponent().getPackageName(),                                      
2732                     new DialogInterface.OnClickListener() {                                              
2733                         public void onClick(DialogInterface dialog, int id) {                            
2734                             startAppShortcutOrInfoActivity(v);                                           
2735                         }                                                                                
2736                     });                                                                                  
2737             return;                                                                                      
2738         }                                                                                                
2739                                                                                                          
2740         // Start activities                                                                              
2741         startAppShortcutOrInfoActivity(v);                                                               
2742     }                                                                                                    
2743                                                                                                          
2744     private void startAppShortcutOrInfoActivity(View v) {                                                
2745         Object tag = v.getTag();                                                                         
2746         final ShortcutInfo shortcut;                                                                     
2747         final Intent intent;                                                                             
2748         if (tag instanceof ShortcutInfo) {                                                               
2749             shortcut = (ShortcutInfo) tag;                                                               
2750             intent = shortcut.intent;                                                                    
2751             int[] pos = new int[2];                                                                      
2752             v.getLocationOnScreen(pos);                                                                  
2753             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2754                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2755                                                                                                          
2756         } else if (tag instanceof AppInfo) {                                                             
2757             shortcut = null;                                                                             
2758             intent = ((AppInfo) tag).intent;                                                             
2759         } else {                                                                                         
2760             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2761         }                                                                                                
2762                                                                                                          
2763         boolean success = startActivitySafely(v, intent, tag);                                           
2764         mStats.recordLaunch(intent, shortcut);                                                           
2765                                                                                                          
2766         if (success && v instanceof BubbleTextView) {                                                    
2767             mWaitingForResume = (BubbleTextView) v;                                                      
2768             mWaitingForResume.setStayPressed(true);                                                      
2769         }                                                                                                
2770     }                                                                                                    
2771                                                                                                          
2772     /**                                                                                                  
2773      * Event handler for a folder icon click.                                                            
2774      *                                                                                                   
2775      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2776      */                                                                                                  
2777     protected void onClickFolderIcon(View v) {                                                           
2778         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2779         if (!(v instanceof FolderIcon)){                                                                 
2780             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2781         }                                                                                                
2782                                                                                                          
2783         FolderIcon folderIcon = (FolderIcon) v;                                                          
2784         final FolderInfo info = folderIcon.getFolderInfo();                                              
2785         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2786                                                                                                          
2787         // If the folder info reports that the associated folder is open, then verify that               
2788         // it is actually opened. There have been a few instances where this gets out of sync.           
2789         if (info.opened && openFolder == null) {                                                         
2790             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2791                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2792             info.opened = false;                                                                         
2793         }                                                                                                
2794                                                                                                          
2795         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2796             // Close any open folder                                                                     
2797             closeFolder();                                                                               
2798             // Open the requested folder                                                                 
2799             openFolder(folderIcon);                                                                      
2800         } else {                                                                                         
2801             // Find the open folder...                                                                   
2802             int folderScreen;                                                                            
2803             if (openFolder != null) {                                                                    
2804                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2805                 // .. and close it                                                                       
2806                 closeFolder(openFolder);                                                                 
2807                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2808                     // Close any folder open on the current screen                                       
2809                     closeFolder();                                                                       
2810                     // Pull the folder onto this screen                                                  
2811                     openFolder(folderIcon);                                                              
2812                 }                                                                                        
2813             }                                                                                            
2814         }                                                                                                
2815     }                                                                                                    
2816                                                                                                          
2817     /**                                                                                                  
2818      * Event handler for the (Add) Widgets button that appears after a long press                        
2819      * on the home screen.                                                                               
2820      */                                                                                                  
2821     protected void onClickAddWidgetButton(View view) {                                                   
2822         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2823         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                             
2824     }                                                                                                    
2825                                                                                                          
2826     /**                                                                                                  
2827      * Event handler for the wallpaper picker button that appears after a long press                     
2828      * on the home screen.                                                                               
2829      */                                                                                                  
2830     protected void onClickWallpaperPicker(View v) {                                                      
2831         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2832         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2833         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2834         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2835     }                                                                                                    
2836                                                                                                          
2837     /**                                                                                                  
2838      * Event handler for a click on the settings button that appears after a long press                  
2839      * on the home screen.                                                                               
2840      */                                                                                                  
2841     protected void onClickSettingsButton(View v) {                                                       
2842         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2843     }                                                                                                    
2844                                                                                                          
2845     public void onTouchDownAllAppsButton(View v) {                                                       
2846         // Provide the same haptic feedback that the system offers for virtual keys.                     
2847         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2848     }                                                                                                    
2849                                                                                                          
2850     public void performHapticFeedbackOnTouchDown(View v) {                                               
2851         // Provide the same haptic feedback that the system offers for virtual keys.                     
2852         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2853     }                                                                                                    
2854                                                                                                          
2855     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2856         if (mHapticFeedbackTouchListener == null) {                                                      
2857             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2858                 @Override                                                                                
2859                 public boolean onTouch(View v, MotionEvent event) {                                      
2860                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2861                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2862                     }                                                                                    
2863                     return false;                                                                        
2864                 }                                                                                        
2865             };                                                                                           
2866         }                                                                                                
2867         return mHapticFeedbackTouchListener;                                                             
2868     }                                                                                                    
2869                                                                                                          
2870     public void onDragStarted(View view) {}                                                              
2871                                                                                                          
2872     /**                                                                                                  
2873      * Called when the user stops interacting with the launcher.                                         
2874      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2875      */                                                                                                  
2876     protected void onInteractionEnd() {}                                                                 
2877                                                                                                          
2878     /**                                                                                                  
2879      * Called when the user starts interacting with the launcher.                                        
2880      * The possible interactions are:                                                                    
2881      *  - open all apps                                                                                  
2882      *  - reorder an app shortcut, or a widget                                                           
2883      *  - open the overview mode.                                                                        
2884      * This is a good time to stop doing things that only make sense                                     
2885      * when the user is on the homescreen and not doing housekeeping.                                    
2886      */                                                                                                  
2887     protected void onInteractionBegin() {}                                                               
2888                                                                                                          
2889     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2890         String packageName = componentName.getPackageName();                                             
2891         try {                                                                                            
2892             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2893             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2894             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2895         } catch (SecurityException e) {                                                                  
2896             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2897             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2898         } catch (ActivityNotFoundException e) {                                                          
2899             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2900             Log.e(TAG, "Unable to launch settings");                                                     
2901         }                                                                                                
2902     }                                                                                                    
2903                                                                                                          
2904     // returns true if the activity was started                                                          
2905     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2906             UserHandleCompat user) {                                                                     
2907         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2908             // System applications cannot be installed. For now, show a toast explaining that.           
2909             // We may give them the option of disabling apps this way.                                   
2910             int messageId = R.string.uninstall_system_app_text;                                          
2911             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2912             return false;                                                                                
2913         } else {                                                                                         
2914             String packageName = componentName.getPackageName();                                         
2915             String className = componentName.getClassName();                                             
2916             Intent intent = new Intent(                                                                  
2917                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2918             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2919                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2920             if (user != null) {                                                                          
2921                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2922             }                                                                                            
2923             startActivity(intent);                                                                       
2924             return true;                                                                                 
2925         }                                                                                                
2926     }                                                                                                    
2927                                                                                                          
2928     boolean startActivity(View v, Intent intent, Object tag) {                                           
2929         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2930         try {                                                                                            
2931             // Only launch using the new animation if the shortcut has not opted out (this is a          
2932             // private contract between launcher and may be ignored in the future).                      
2933             boolean useLaunchAnimation = (v != null) &&                                                  
2934                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2935             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2936             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2937                                                                                                          
2938             UserHandleCompat user = null;                                                                
2939             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2940                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2941                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2942             }                                                                                            
2943                                                                                                          
2944             Bundle optsBundle = null;                                                                    
2945             if (useLaunchAnimation) {                                                                    
2946                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2947                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2948                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2949                 optsBundle = opts.toBundle();                                                            
2950             }                                                                                            
2951                                                                                                          
2952             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2953                 // Could be launching some bookkeeping activity                                          
2954                 startActivity(intent, optsBundle);                                                       
2955             } else {                                                                                     
2956                 // TODO Component can be null when shortcuts are supported for secondary user            
2957                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2958                         intent.getSourceBounds(), optsBundle);                                           
2959             }                                                                                            
2960             return true;                                                                                 
2961         } catch (SecurityException e) {                                                                  
2962             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2963             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2964                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2965                     "or use the exported attribute for this activity. "                                  
2966                     + "tag="+ tag + " intent=" + intent, e);                                             
2967         }                                                                                                
2968         return false;                                                                                    
2969     }                                                                                                    
2970                                                                                                          
2971     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2972         boolean success = false;                                                                         
2973         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2974             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2975             return false;                                                                                
2976         }                                                                                                
2977         try {                                                                                            
2978             success = startActivity(v, intent, tag);                                                     
2979         } catch (ActivityNotFoundException e) {                                                          
2980             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2981             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2982         }                                                                                                
2983         return success;                                                                                  
2984     }                                                                                                    
2985                                                                                                          
2986     /**                                                                                                  
2987      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2988      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2989      */                                                                                                  
2990     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2991         final int width = fi.getMeasuredWidth();                                                         
2992         final int height = fi.getMeasuredHeight();                                                       
2993                                                                                                          
2994         // Lazy load ImageView, Bitmap and Canvas                                                        
2995         if (mFolderIconImageView == null) {                                                              
2996             mFolderIconImageView = new ImageView(this);                                                  
2997         }                                                                                                
2998         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2999                 mFolderIconBitmap.getHeight() != height) {                                               
3000             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3001             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3002         }                                                                                                
3003                                                                                                          
3004         DragLayer.LayoutParams lp;                                                                       
3005         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3006             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3007         } else {                                                                                         
3008             lp = new DragLayer.LayoutParams(width, height);                                              
3009         }                                                                                                
3010                                                                                                          
3011         // The layout from which the folder is being opened may be scaled, adjust the starting           
3012         // view size by this scale factor.                                                               
3013         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3014         lp.customPosition = true;                                                                        
3015         lp.x = mRectForFolderAnimation.left;                                                             
3016         lp.y = mRectForFolderAnimation.top;                                                              
3017         lp.width = (int) (scale * width);                                                                
3018         lp.height = (int) (scale * height);                                                              
3019                                                                                                          
3020         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3021         fi.draw(mFolderIconCanvas);                                                                      
3022         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3023         if (fi.getFolder() != null) {                                                                    
3024             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3025             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3026         }                                                                                                
3027         // Just in case this image view is still in the drag layer from a previous animation,            
3028         // we remove it and re-add it.                                                                   
3029         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3030             mDragLayer.removeView(mFolderIconImageView);                                                 
3031         }                                                                                                
3032         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3033         if (fi.getFolder() != null) {                                                                    
3034             fi.getFolder().bringToFront();                                                               
3035         }                                                                                                
3036     }                                                                                                    
3037                                                                                                          
3038     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3039         if (fi == null) return;                                                                          
3040         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3041         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3042         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3043                                                                                                          
3044         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3045         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3046             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3047             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3048             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3049         }                                                                                                
3050                                                                                                          
3051         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3052         copyFolderIconToImage(fi);                                                                       
3053         fi.setVisibility(View.INVISIBLE);                                                                
3054                                                                                                          
3055         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3056                 scaleX, scaleY);                                                                         
3057         if (Utilities.isLmpOrAbove()) {                                                                  
3058             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3059         }                                                                                                
3060         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3061         oa.start();                                                                                      
3062     }                                                                                                    
3063                                                                                                          
3064     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3065         if (fi == null) return;                                                                          
3066         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3067         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3068         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3069                                                                                                          
3070         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3071                                                                                                          
3072         // We remove and re-draw the FolderIcon in-case it has changed                                   
3073         mDragLayer.removeView(mFolderIconImageView);                                                     
3074         copyFolderIconToImage(fi);                                                                       
3075         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3076                 scaleX, scaleY);                                                                         
3077         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3078         oa.addListener(new AnimatorListenerAdapter() {                                                   
3079             @Override                                                                                    
3080             public void onAnimationEnd(Animator animation) {                                             
3081                 if (cl != null) {                                                                        
3082                     cl.clearFolderLeaveBehind();                                                         
3083                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3084                     mDragLayer.removeView(mFolderIconImageView);                                         
3085                     fi.setVisibility(View.VISIBLE);                                                      
3086                 }                                                                                        
3087             }                                                                                            
3088         });                                                                                              
3089         oa.start();                                                                                      
3090     }                                                                                                    
3091                                                                                                          
3092     /**                                                                                                  
3093      * Opens the user folder described by the specified tag. The opening of the folder                   
3094      * is animated relative to the specified View. If the View is null, no animation                     
3095      * is played.                                                                                        
3096      *                                                                                                   
3097      * @param folderInfo The FolderInfo describing the folder to open.                                   
3098      */                                                                                                  
3099     public void openFolder(FolderIcon folderIcon) {                                                      
3100         Folder folder = folderIcon.getFolder();                                                          
3101         FolderInfo info = folder.mInfo;                                                                  
3102                                                                                                          
3103         info.opened = true;                                                                              
3104                                                                                                          
3105         // Just verify that the folder hasn't already been added to the DragLayer.                       
3106         // There was a one-off crash where the folder had a parent already.                              
3107         if (folder.getParent() == null) {                                                                
3108             mDragLayer.addView(folder);                                                                  
3109             mDragController.addDropTarget((DropTarget) folder);                                          
3110         } else {                                                                                         
3111             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3112                     folder.getParent() + ").");                                                          
3113         }                                                                                                
3114         folder.animateOpen();                                                                            
3115         growAndFadeOutFolderIcon(folderIcon);                                                            
3116                                                                                                          
3117         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3118         // the workspace items                                                                           
3119         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3120         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3121     }                                                                                                    
3122                                                                                                          
3123     public void closeFolder() {                                                                          
3124         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3125         if (folder != null) {                                                                            
3126             if (folder.isEditingName()) {                                                                
3127                 folder.dismissEditingName();                                                             
3128             }                                                                                            
3129             closeFolder(folder);                                                                         
3130         }                                                                                                
3131     }                                                                                                    
3132                                                                                                          
3133     void closeFolder(Folder folder) {                                                                    
3134         folder.getInfo().opened = false;                                                                 
3135                                                                                                          
3136         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3137         if (parent != null) {                                                                            
3138             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3139             shrinkAndFadeInFolderIcon(fi);                                                               
3140         }                                                                                                
3141         folder.animateClosed();                                                                          
3142                                                                                                          
3143         // Notify the accessibility manager that this folder "window" has disappeard and no              
3144         // longer occludeds the workspace items                                                          
3145         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3146     }                                                                                                    
3147                                                                                                          
3148     public boolean onLongClick(View v) {                                                                 
3149         if (!isDraggingEnabled()) return false;                                                          
3150         if (isWorkspaceLocked()) return false;                                                           
3151         if (mState != State.WORKSPACE) return false;                                                     
3152                                                                                                          
3153         if (v instanceof Workspace) {                                                                    
3154             if (!mWorkspace.isInOverviewMode()) {                                                        
3155                 if (mWorkspace.enterOverviewMode()) {                                                    
3156                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3157                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3158                     return true;                                                                         
3159                 } else {                                                                                 
3160                     return false;                                                                        
3161                 }                                                                                        
3162             } else {                                                                                     
3163                 return false;                                                                            
3164             }                                                                                            
3165         }                                                                                                
3166                                                                                                          
3167         CellLayout.CellInfo longClickCellInfo = null;                                                    
3168         View itemUnderLongClick = null;                                                                  
3169         if (v.getTag() instanceof ItemInfo) {                                                            
3170             ItemInfo info = (ItemInfo) v.getTag();                                                       
3171             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3172             itemUnderLongClick = longClickCellInfo.cell;                                                 
3173             resetAddInfo();                                                                              
3174         }                                                                                                
3175                                                                                                          
3176         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3177         // on hotseat items.                                                                             
3178         final boolean inHotseat = isHotseatLayout(v);                                                    
3179         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3180         if (allowLongPress && !mDragController.isDragging()) {                                           
3181             if (itemUnderLongClick == null) {                                                            
3182                 // User long pressed on empty space                                                      
3183                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3184                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3185                 if (mWorkspace.isInOverviewMode()) {                                                     
3186                     mWorkspace.startReordering(v);                                                       
3187                 } else {                                                                                 
3188                     mWorkspace.enterOverviewMode();                                                      
3189                 }                                                                                        
3190             } else {                                                                                     
3191                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3192                         mHotseat.getOrderInHotseat(                                                      
3193                                 longClickCellInfo.cellX,                                                 
3194                                 longClickCellInfo.cellY));                                               
3195                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3196                     // User long pressed on an item                                                      
3197                     mWorkspace.startDrag(longClickCellInfo);                                             
3198                 }                                                                                        
3199             }                                                                                            
3200         }                                                                                                
3201         return true;                                                                                     
3202     }                                                                                                    
3203                                                                                                          
3204     boolean isHotseatLayout(View layout) {                                                               
3205         return mHotseat != null && layout != null &&                                                     
3206                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3207     }                                                                                                    
3208                                                                                                          
3209     /**                                                                                                  
3210      * Returns the CellLayout of the specified container at the specified screen.                        
3211      */                                                                                                  
3212     CellLayout getCellLayout(long container, long screenId) {                                            
3213         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3214             if (mHotseat != null) {                                                                      
3215                 return mHotseat.getLayout();                                                             
3216             } else {                                                                                     
3217                 return null;                                                                             
3218             }                                                                                            
3219         } else {                                                                                         
3220             return (CellLayout) mWorkspace.getScreenWithId(screenId);                                    
3221         }                                                                                                
3222     }                                                                                                    
3223                                                                                                          
3224     public boolean isAllAppsVisible() {                                                                  
3225         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);             
3226     }                                                                                                    
3227                                                                                                          
3228     private void setWorkspaceBackground(boolean workspace) {                                             
3229         mLauncherView.setBackground(workspace ?                                                          
3230                 mWorkspaceBackgroundDrawable : null);                                                    
3231     }                                                                                                    
3232                                                                                                          
3233     protected void changeWallpaperVisiblity(boolean visible) {                                           
3234         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3235         int curflags = getWindow().getAttributes().flags                                                 
3236                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3237         if (wpflags != curflags) {                                                                       
3238             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3239         }                                                                                                
3240         setWorkspaceBackground(visible);                                                                 
3241     }                                                                                                    
3242                                                                                                          
3243     private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {    
3244         if (v instanceof LauncherTransitionable) {                                                       
3245             ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);       
3246         }                                                                                                
3247     }                                                                                                    
3248                                                                                                          
3249     private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {      
3250         if (v instanceof LauncherTransitionable) {                                                       
3251             ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);         
3252         }                                                                                                
3253                                                                                                          
3254         // Update the workspace transition step as well                                                  
3255         dispatchOnLauncherTransitionStep(v, 0f);                                                         
3256     }                                                                                                    
3257                                                                                                          
3258     private void dispatchOnLauncherTransitionStep(View v, float t) {                                     
3259         if (v instanceof LauncherTransitionable) {                                                       
3260             ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                              
3261         }                                                                                                
3262     }                                                                                                    
3263                                                                                                          
3264     private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {        
3265         if (v instanceof LauncherTransitionable) {                                                       
3266             ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);           
3267         }                                                                                                
3268                                                                                                          
3269         // Update the workspace transition step as well                                                  
3270         dispatchOnLauncherTransitionStep(v, 1f);                                                         
3271     }                                                                                                    
3272                                                                                                          
3273     /**                                                                                                  
3274      * Things to test when changing the following seven functions.                                       
3275      *   - Home from workspace                                                                           
3276      *          - from center screen                                                                     
3277      *          - from other screens                                                                     
3278      *   - Home from all apps                                                                            
3279      *          - from center screen                                                                     
3280      *          - from other screens                                                                     
3281      *   - Back from all apps                                                                            
3282      *          - from center screen                                                                     
3283      *          - from other screens                                                                     
3284      *   - Launch app from workspace and quit                                                            
3285      *          - with back                                                                              
3286      *          - with home                                                                              
3287      *   - Launch app from all apps and quit                                                             
3288      *          - with back                                                                              
3289      *          - with home                                                                              
3290      *   - Go to a screen that's not the default, then all                                               
3291      *     apps, and launch and app, and go back                                                         
3292      *          - with back                                                                              
3293      *          -with home                                                                               
3294      *   - On workspace, long press power and go back                                                    
3295      *          - with back                                                                              
3296      *          - with home                                                                              
3297      *   - On all apps, long press power and go back                                                     
3298      *          - with back                                                                              
3299      *          - with home                                                                              
3300      *   - On workspace, power off                                                                       
3301      *   - On all apps, power off                                                                        
3302      *   - Launch an app and turn off the screen while in that app                                       
3303      *          - Go back with home key                                                                  
3304      *          - Go back with back key  TODO: make this not go to workspace                             
3305      *          - From all apps                                                                          
3306      *          - From workspace                                                                         
3307      *   - Enter and exit car mode (becuase it causes an extra configuration changed)                    
3308      *          - From all apps                                                                          
3309      *          - From the center workspace                                                              
3310      *          - From another workspace                                                                 
3311      */                                                                                                  
3312                                                                                                          
3313     /**                                                                                                  
3314      * Zoom the camera out from the workspace to reveal 'toView'.                                        
3315      * Assumes that the view to show is anchored at either the very top or very bottom                   
3316      * of the screen.                                                                                    
3317      */                                                                                                  
3318     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {           
3319         AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();         
3320         showAppsCustomizeHelper(animated, springLoaded, contentType);                                    
3321     }                                                                                                    
3322                                                                                                          
3323     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,             
3324                                          final AppsCustomizePagedView.ContentType contentType) {         
3325         if (mStateAnimation != null) {                                                                   
3326             mStateAnimation.setDuration(0);                                                              
3327             mStateAnimation.cancel();                                                                    
3328             mStateAnimation = null;                                                                      
3329         }                                                                                                
3330                                                                                                          
3331         boolean material = Utilities.isLmpOrAbove();                                                     
3332                                                                                                          
3333         final Resources res = getResources();                                                            
3334                                                                                                          
3335         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                   
3336         final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);               
3337         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);             
3338         final int itemsAlphaStagger =                                                                    
3339                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3340                                                                                                          
3341         final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);       
3342         final View fromView = mWorkspace;                                                                
3343         final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                       
3344                                                                                                          
3345         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3346                                                                                                          
3347         Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?     
3348                 Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                         
3349         Animator workspaceAnim =                                                                         
3350                 mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                
3351         if (!LauncherAppState.isDisableAllApps()                                                         
3352                 || contentType == AppsCustomizePagedView.ContentType.Widgets) {                          
3353             // Set the content type for the all apps/widgets space                                       
3354             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                  
3355         }                                                                                                
3356                                                                                                          
3357         // If for some reason our views aren't initialized, don't animate                                
3358         boolean initialized = getAllAppsButton() != null;                                                
3359                                                                                                          
3360         if (animated && initialized) {                                                                   
3361             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3362             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3363                     toView.findViewById(R.id.apps_customize_pane_content);                               
3364                                                                                                          
3365             final View page = content.getPageAt(content.getCurrentPage());                               
3366             final View revealView = toView.findViewById(R.id.fake_page);                                 
3367                                                                                                          
3368             final float initialPanelAlpha = 1f;                                                          
3369                                                                                                          
3370             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;      
3371             if (isWidgetTray) {                                                                          
3372                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                
3373             } else {                                                                                     
3374                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                     
3375             }                                                                                            
3376                                                                                                          
3377             // Hide the real page background, and swap in the fake one                                   
3378             content.setPageBackgroundsVisible(false);                                                    
3379             revealView.setVisibility(View.VISIBLE);                                                      
3380             // We need to hide this view as the animation start will be posted.                          
3381             revealView.setAlpha(0);                                                                      
3382                                                                                                          
3383             int width = revealView.getMeasuredWidth();                                                   
3384             int height = revealView.getMeasuredHeight();                                                 
3385             float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);         
3386                                                                                                          
3387             revealView.setTranslationY(0);                                                               
3388             revealView.setTranslationX(0);                                                               
3389                                                                                                          
3390             // Get the y delta between the center of the page and the center of the all apps button      
3391             int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                
3392                     getAllAppsButton(), null);                                                           
3393                                                                                                          
3394             float alpha = 0;                                                                             
3395             float xDrift = 0;                                                                            
3396             float yDrift = 0;                                                                            
3397             if (material) {                                                                              
3398                 alpha = isWidgetTray ? 0.3f : 1f;                                                        
3399                 yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                             
3400                 xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                      
3401             } else {                                                                                     
3402                 yDrift = 2 * height / 3;                                                                 
3403                 xDrift = 0;                                                                              
3404             }                                                                                            
3405             final float initAlpha = alpha;                                                               
3406                                                                                                          
3407             revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                     
3408             layerViews.add(revealView);                                                                  
3409             PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);      
3410             PropertyValuesHolder panelDriftY =                                                           
3411                     PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                             
3412             PropertyValuesHolder panelDriftX =                                                           
3413                     PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                             
3414                                                                                                          
3415             ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,        
3416                     panelAlpha, panelDriftY, panelDriftX);                                               
3417                                                                                                          
3418             panelAlphaAndDrift.setDuration(revealDuration);                                              
3419             panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                   
3420                                                                                                          
3421             mStateAnimation.play(panelAlphaAndDrift);                                                    
3422                                                                                                          
3423             if (page != null) {                                                                          
3424                 page.setVisibility(View.VISIBLE);                                                        
3425                 page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3426                 layerViews.add(page);                                                                    
3427                                                                                                          
3428                 ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);      
3429                 page.setTranslationY(yDrift);                                                            
3430                 pageDrift.setDuration(revealDuration);                                                   
3431                 pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                        
3432                 pageDrift.setStartDelay(itemsAlphaStagger);                                              
3433                 mStateAnimation.play(pageDrift);                                                         
3434                                                                                                          
3435                 page.setAlpha(0f);                                                                       
3436                 ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);               
3437                 itemsAlpha.setDuration(revealDuration);                                                  
3438                 itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                            
3439                 itemsAlpha.setStartDelay(itemsAlphaStagger);                                             
3440                 mStateAnimation.play(itemsAlpha);                                                        
3441             }                                                                                            
3442                                                                                                          
3443             View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);               
3444             pageIndicators.setAlpha(0.01f);                                                              
3445             ObjectAnimator indicatorsAlpha =                                                             
3446                     ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                 
3447             indicatorsAlpha.setDuration(revealDuration);                                                 
3448             mStateAnimation.play(indicatorsAlpha);                                                       
3449                                                                                                          
3450             if (material) {                                                                              
3451                 final View allApps = getAllAppsButton();                                                 
3452                 int allAppsButtonSize = LauncherAppState.getInstance().                                  
3453                         getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                     
3454                 float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                            
3455                 Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,         
3456                                 height / 2, startRadius, revealRadius);                                  
3457                 reveal.setDuration(revealDuration);                                                      
3458                 reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                           
3459                                                                                                          
3460                 reveal.addListener(new AnimatorListenerAdapter() {                                       
3461                     public void onAnimationStart(Animator animation) {                                   
3462                         if (!isWidgetTray) {                                                             
3463                             allApps.setVisibility(View.INVISIBLE);                                       
3464                         }                                                                                
3465                     }                                                                                    
3466                     public void onAnimationEnd(Animator animation) {                                     
3467                         if (!isWidgetTray) {                                                             
3468                             allApps.setVisibility(View.VISIBLE);                                         
3469                         }                                                                                
3470                     }                                                                                    
3471                 });                                                                                      
3472                 mStateAnimation.play(reveal);                                                            
3473             }                                                                                            
3474                                                                                                          
3475             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3476                 @Override                                                                                
3477                 public void onAnimationEnd(Animator animation) {                                         
3478                     dispatchOnLauncherTransitionEnd(fromView, animated, false);                          
3479                     dispatchOnLauncherTransitionEnd(toView, animated, false);                            
3480                                                                                                          
3481                     revealView.setVisibility(View.INVISIBLE);                                            
3482                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3483                     if (page != null) {                                                                  
3484                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3485                     }                                                                                    
3486                     content.setPageBackgroundsVisible(true);                                             
3487                                                                                                          
3488                     // Hide the search bar                                                               
3489                     if (mSearchDropTargetBar != null) {                                                  
3490                         mSearchDropTargetBar.hideSearchBar(false);                                       
3491                     }                                                                                    
3492                 }                                                                                        
3493                                                                                                          
3494             });                                                                                          
3495                                                                                                          
3496             if (workspaceAnim != null) {                                                                 
3497                 mStateAnimation.play(workspaceAnim);                                                     
3498             }                                                                                            
3499                                                                                                          
3500             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3501             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3502             final AnimatorSet stateAnimation = mStateAnimation;                                          
3503             final Runnable startAnimRunnable = new Runnable() {                                          
3504                 public void run() {                                                                      
3505                     // Check that mStateAnimation hasn't changed while                                   
3506                     // we waited for a layout/draw pass                                                  
3507                     if (mStateAnimation != stateAnimation)                                               
3508                         return;                                                                          
3509                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3510                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3511                                                                                                          
3512                     revealView.setAlpha(initAlpha);                                                      
3513                     if (Utilities.isLmpOrAbove()) {                                                      
3514                         for (int i = 0; i < layerViews.size(); i++) {                                    
3515                             View v = layerViews.get(i);                                                  
3516                             if (v != null) {                                                             
3517                                 boolean attached = true;                                                 
3518                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3519                                     attached = v.isAttachedToWindow();                                   
3520                                 }                                                                        
3521                                 if (attached) v.buildLayer();                                            
3522                             }                                                                            
3523                         }                                                                                
3524                     }                                                                                    
3525                     mStateAnimation.start();                                                             
3526                 }                                                                                        
3527             };                                                                                           
3528             toView.bringToFront();                                                                       
3529             toView.setVisibility(View.VISIBLE);                                                          
3530             toView.post(startAnimRunnable);                                                              
3531         } else {                                                                                         
3532             toView.setTranslationX(0.0f);                                                                
3533             toView.setTranslationY(0.0f);                                                                
3534             toView.setScaleX(1.0f);                                                                      
3535             toView.setScaleY(1.0f);                                                                      
3536             toView.setVisibility(View.VISIBLE);                                                          
3537             toView.bringToFront();                                                                       
3538                                                                                                          
3539             if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                      
3540                 // Hide the search bar                                                                   
3541                 if (mSearchDropTargetBar != null) {                                                      
3542                     mSearchDropTargetBar.hideSearchBar(false);                                           
3543                 }                                                                                        
3544             }                                                                                            
3545             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3546             dispatchOnLauncherTransitionStart(fromView, animated, false);                                
3547             dispatchOnLauncherTransitionEnd(fromView, animated, false);                                  
3548             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3549             dispatchOnLauncherTransitionStart(toView, animated, false);                                  
3550             dispatchOnLauncherTransitionEnd(toView, animated, false);                                    
3551         }                                                                                                
3552     }                                                                                                    
3553                                                                                                          
3554     /**                                                                                                  
3555      * Zoom the camera back into the workspace, hiding 'fromView'.                                       
3556      * This is the opposite of showAppsCustomizeHelper.                                                  
3557      * @param animated If true, the transition will be animated.                                         
3558      */                                                                                                  
3559     private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                
3560             final boolean springLoaded, final Runnable onCompleteRunnable) {                             
3561                                                                                                          
3562         if (mStateAnimation != null) {                                                                   
3563             mStateAnimation.setDuration(0);                                                              
3564             mStateAnimation.cancel();                                                                    
3565             mStateAnimation = null;                                                                      
3566         }                                                                                                
3567                                                                                                          
3568         boolean material = Utilities.isLmpOrAbove();                                                     
3569         Resources res = getResources();                                                                  
3570                                                                                                          
3571         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                  
3572         final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);           
3573         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);            
3574         final int itemsAlphaStagger =                                                                    
3575                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3576                                                                                                          
3577         final float scaleFactor = (float)                                                                
3578                 res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                           
3579         final View fromView = mAppsCustomizeTabHost;                                                     
3580         final View toView = mWorkspace;                                                                  
3581         Animator workspaceAnim = null;                                                                   
3582         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3583                                                                                                          
3584         if (toState == Workspace.State.NORMAL) {                                                         
3585             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3586                     toState, animated, layerViews);                                                      
3587         } else if (toState == Workspace.State.SPRING_LOADED ||                                           
3588                 toState == Workspace.State.OVERVIEW) {                                                   
3589             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3590                     toState, animated, layerViews);                                                      
3591         }                                                                                                
3592                                                                                                          
3593         // If for some reason our views aren't initialized, don't animate                                
3594         boolean initialized = getAllAppsButton() != null;                                                
3595                                                                                                          
3596         if (animated && initialized) {                                                                   
3597             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3598             if (workspaceAnim != null) {                                                                 
3599                 mStateAnimation.play(workspaceAnim);                                                     
3600             }                                                                                            
3601                                                                                                          
3602             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3603                     fromView.findViewById(R.id.apps_customize_pane_content);                             
3604                                                                                                          
3605             final View page = content.getPageAt(content.getNextPage());                                  
3606                                                                                                          
3607             // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases        
3608             int count = content.getChildCount();                                                         
3609             for (int i = 0; i < count; i++) {                                                            
3610                 View child = content.getChildAt(i);                                                      
3611                 if (child != page) {                                                                     
3612                     child.setVisibility(View.INVISIBLE);                                                 
3613                 }                                                                                        
3614             }                                                                                            
3615             final View revealView = fromView.findViewById(R.id.fake_page);                               
3616                                                                                                          
3617             // hideAppsCustomizeHelper is called in some cases when it is already hidden                 
3618             // don't perform all these no-op animations. In particularly, this was causing               
3619             // the all-apps button to pop in and out.                                                    
3620             if (fromView.getVisibility() == View.VISIBLE) {                                              
3621                 AppsCustomizePagedView.ContentType contentType = content.getContentType();               
3622                 final boolean isWidgetTray =                                                             
3623                         contentType == AppsCustomizePagedView.ContentType.Widgets;                       
3624                                                                                                          
3625                 if (isWidgetTray) {                                                                      
3626                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));            
3627                 } else {                                                                                 
3628                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                 
3629                 }                                                                                        
3630                                                                                                          
3631                 int width = revealView.getMeasuredWidth();                                               
3632                 int height = revealView.getMeasuredHeight();                                             
3633                 float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);     
3634                                                                                                          
3635                 // Hide the real page background, and swap in the fake one                               
3636                 revealView.setVisibility(View.VISIBLE);                                                  
3637                 content.setPageBackgroundsVisible(false);                                                
3638                                                                                                          
3639                 final View allAppsButton = getAllAppsButton();                                           
3640                 revealView.setTranslationY(0);                                                           
3641                 int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,            
3642                         allAppsButton, null);                                                            
3643                                                                                                          
3644                 float xDrift = 0;                                                                        
3645                 float yDrift = 0;                                                                        
3646                 if (material) {                                                                          
3647                     yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                         
3648                     xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                  
3649                 } else {                                                                                 
3650                     yDrift = 5 * height / 4;                                                             
3651                     xDrift = 0;                                                                          
3652                 }                                                                                        
3653                                                                                                          
3654                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                 
3655                 TimeInterpolator decelerateInterpolator = material ?                                     
3656                         new LogDecelerateInterpolator(100, 0) :                                          
3657                         new LogDecelerateInterpolator(30, 0);                                            
3658                                                                                                          
3659                 // The vertical motion of the apps panel should be delayed by one frame                  
3660                 // from the conceal animation in order to give the right feel. We correpsondingly        
3661                 // shorten the duration so that the slide and conceal end at the same time.              
3662                 ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",       
3663                         0, yDrift);                                                                      
3664                 panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3665                 panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3666                 panelDriftY.setInterpolator(decelerateInterpolator);                                     
3667                 mStateAnimation.play(panelDriftY);                                                       
3668                                                                                                          
3669                 ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",       
3670                         0, xDrift);                                                                      
3671                 panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3672                 panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3673                 panelDriftX.setInterpolator(decelerateInterpolator);                                     
3674                 mStateAnimation.play(panelDriftX);                                                       
3675                                                                                                          
3676                 if (isWidgetTray || !material) {                                                         
3677                     float finalAlpha = material ? 0.4f : 0f;                                             
3678                     revealView.setAlpha(1f);                                                             
3679                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",           
3680                             1f, finalAlpha);                                                             
3681                     panelAlpha.setDuration(revealDuration);                                              
3682                     panelAlpha.setInterpolator(material ? decelerateInterpolator :                       
3683                         new AccelerateInterpolator(1.5f));                                               
3684                     mStateAnimation.play(panelAlpha);                                                    
3685                 }                                                                                        
3686                                                                                                          
3687                 if (page != null) {                                                                      
3688                     page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                   
3689                                                                                                          
3690                     ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",           
3691                             0, yDrift);                                                                  
3692                     page.setTranslationY(0);                                                             
3693                     pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                          
3694                     pageDrift.setInterpolator(decelerateInterpolator);                                   
3695                     pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                     
3696                     mStateAnimation.play(pageDrift);                                                     
3697                                                                                                          
3698                     page.setAlpha(1f);                                                                   
3699                     ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);        
3700                     itemsAlpha.setDuration(100);                                                         
3701                     itemsAlpha.setInterpolator(decelerateInterpolator);                                  
3702                     mStateAnimation.play(itemsAlpha);                                                    
3703                 }                                                                                        
3704                                                                                                          
3705                 View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);         
3706                 pageIndicators.setAlpha(1f);                                                             
3707                 ObjectAnimator indicatorsAlpha =                                                         
3708                         LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                          
3709                 indicatorsAlpha.setDuration(revealDuration);                                             
3710                 indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                       
3711                 mStateAnimation.play(indicatorsAlpha);                                                   
3712                                                                                                          
3713                 width = revealView.getMeasuredWidth();                                                   
3714                                                                                                          
3715                 if (material) {                                                                          
3716                     if (!isWidgetTray) {                                                                 
3717                         allAppsButton.setVisibility(View.INVISIBLE);                                     
3718                     }                                                                                    
3719                     int allAppsButtonSize = LauncherAppState.getInstance().                              
3720                             getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                 
3721                     float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                        
3722                     Animator reveal =                                                                    
3723                             LauncherAnimUtils.createCircularReveal(revealView, width / 2,                
3724                                     height / 2, revealRadius, finalRadius);                              
3725                     reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                       
3726                     reveal.setDuration(revealDuration);                                                  
3727                     reveal.setStartDelay(itemsAlphaStagger);                                             
3728                                                                                                          
3729                     reveal.addListener(new AnimatorListenerAdapter() {                                   
3730                         public void onAnimationEnd(Animator animation) {                                 
3731                             revealView.setVisibility(View.INVISIBLE);                                    
3732                             if (!isWidgetTray) {                                                         
3733                                 allAppsButton.setVisibility(View.VISIBLE);                               
3734                             }                                                                            
3735                         }                                                                                
3736                     });                                                                                  
3737                                                                                                          
3738                     mStateAnimation.play(reveal);                                                        
3739                 }                                                                                        
3740                                                                                                          
3741                 dispatchOnLauncherTransitionPrepare(fromView, animated, true);                           
3742                 dispatchOnLauncherTransitionPrepare(toView, animated, true);                             
3743                 mAppsCustomizeContent.stopScrolling();                                                   
3744             }                                                                                            
3745                                                                                                          
3746             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3747                 @Override                                                                                
3748                 public void onAnimationEnd(Animator animation) {                                         
3749                     fromView.setVisibility(View.GONE);                                                   
3750                     dispatchOnLauncherTransitionEnd(fromView, animated, true);                           
3751                     dispatchOnLauncherTransitionEnd(toView, animated, true);                             
3752                     if (onCompleteRunnable != null) {                                                    
3753                         onCompleteRunnable.run();                                                        
3754                     }                                                                                    
3755                                                                                                          
3756                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3757                     if (page != null) {                                                                  
3758                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3759                     }                                                                                    
3760                     content.setPageBackgroundsVisible(true);                                             
3761                     // Unhide side pages                                                                 
3762                     int count = content.getChildCount();                                                 
3763                     for (int i = 0; i < count; i++) {                                                    
3764                         View child = content.getChildAt(i);                                              
3765                         child.setVisibility(View.VISIBLE);                                               
3766                     }                                                                                    
3767                                                                                                          
3768                     // Reset page transforms                                                             
3769                     if (page != null) {                                                                  
3770                         page.setTranslationX(0);                                                         
3771                         page.setTranslationY(0);                                                         
3772                         page.setAlpha(1);                                                                
3773                     }                                                                                    
3774                     content.setCurrentPage(content.getNextPage());                                       
3775                                                                                                          
3776                     mAppsCustomizeContent.updateCurrentPageScroll();                                     
3777                 }                                                                                        
3778             });                                                                                          
3779                                                                                                          
3780             final AnimatorSet stateAnimation = mStateAnimation;                                          
3781             final Runnable startAnimRunnable = new Runnable() {                                          
3782                 public void run() {                                                                      
3783                     // Check that mStateAnimation hasn't changed while                                   
3784                     // we waited for a layout/draw pass                                                  
3785                     if (mStateAnimation != stateAnimation)                                               
3786                         return;                                                                          
3787                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3788                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3789                                                                                                          
3790                     if (Utilities.isLmpOrAbove()) {                                                      
3791                         for (int i = 0; i < layerViews.size(); i++) {                                    
3792                             View v = layerViews.get(i);                                                  
3793                             if (v != null) {                                                             
3794                                 boolean attached = true;                                                 
3795                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3796                                     attached = v.isAttachedToWindow();                                   
3797                                 }                                                                        
3798                                 if (attached) v.buildLayer();                                            
3799                             }                                                                            
3800                         }                                                                                
3801                     }                                                                                    
3802                     mStateAnimation.start();                                                             
3803                 }                                                                                        
3804             };                                                                                           
3805             fromView.post(startAnimRunnable);                                                            
3806         } else {                                                                                         
3807             fromView.setVisibility(View.GONE);                                                           
3808             dispatchOnLauncherTransitionPrepare(fromView, animated, true);                               
3809             dispatchOnLauncherTransitionStart(fromView, animated, true);                                 
3810             dispatchOnLauncherTransitionEnd(fromView, animated, true);                                   
3811             dispatchOnLauncherTransitionPrepare(toView, animated, true);                                 
3812             dispatchOnLauncherTransitionStart(toView, animated, true);                                   
3813             dispatchOnLauncherTransitionEnd(toView, animated, true);                                     
3814         }                                                                                                
3815     }                                                                                                    
3816                                                                                                          
3817     @Override                                                                                            
3818     public void onTrimMemory(int level) {                                                                
3819         super.onTrimMemory(level);                                                                       
3820         if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                         
3821             mAppsCustomizeTabHost.onTrimMemory();                                                        
3822         }                                                                                                
3823     }                                                                                                    
3824                                                                                                          
3825     protected void showWorkspace(boolean animated) {                                                     
3826         showWorkspace(animated, null);                                                                   
3827     }                                                                                                    
3828                                                                                                          
3829     protected void showWorkspace() {                                                                     
3830         showWorkspace(true);                                                                             
3831     }                                                                                                    
3832                                                                                                          
3833     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3834         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3835             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3836             mWorkspace.setVisibility(View.VISIBLE);                                                      
3837             hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);        
3838                                                                                                          
3839             // Show the search bar (only animate if we were showing the drop target bar in spring        
3840             // loaded mode)                                                                              
3841             if (mSearchDropTargetBar != null) {                                                          
3842                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3843             }                                                                                            
3844                                                                                                          
3845             // Set focus to the AppsCustomize button                                                     
3846             if (mAllAppsButton != null) {                                                                
3847                 mAllAppsButton.requestFocus();                                                           
3848             }                                                                                            
3849         }                                                                                                
3850                                                                                                          
3851         // Change the state *after* we've called all the transition code                                 
3852         mState = State.WORKSPACE;                                                                        
3853                                                                                                          
3854         // Resume the auto-advance of widgets                                                            
3855         mUserPresent = true;                                                                             
3856         updateRunning();                                                                                 
3857                                                                                                          
3858         // Send an accessibility event to announce the context change                                    
3859         getWindow().getDecorView()                                                                       
3860                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3861                                                                                                          
3862         onWorkspaceShown(animated);                                                                      
3863     }                                                                                                    
3864                                                                                                          
3865     void showOverviewMode(boolean animated) {                                                            
3866         mWorkspace.setVisibility(View.VISIBLE);                                                          
3867         hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                        
3868         mState = State.WORKSPACE;                                                                        
3869         onWorkspaceShown(animated);                                                                      
3870     }                                                                                                    
3871                                                                                                          
3872     public void onWorkspaceShown(boolean animated) {                                                     
3873     }                                                                                                    
3874                                                                                                          
3875     void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                   
3876                      boolean resetPageToZero) {                                                          
3877         if (mState != State.WORKSPACE) return;                                                           
3878                                                                                                          
3879         if (resetPageToZero) {                                                                           
3880             mAppsCustomizeTabHost.reset();                                                               
3881         }                                                                                                
3882         showAppsCustomizeHelper(animated, false, contentType);                                           
3883         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3884             @Override                                                                                    
3885             public void run() {                                                                          
3886                 // We post this in-case the all apps view isn't yet constructed.                         
3887                 mAppsCustomizeTabHost.requestFocus();                                                    
3888             }                                                                                            
3889         });                                                                                              
3890                                                                                                          
3891         // Change the state *after* we've called all the transition code                                 
3892         mState = State.APPS_CUSTOMIZE;                                                                   
3893                                                                                                          
3894         // Pause the auto-advance of widgets until we are out of AllApps                                 
3895         mUserPresent = false;                                                                            
3896         updateRunning();                                                                                 
3897         closeFolder();                                                                                   
3898                                                                                                          
3899         // Send an accessibility event to announce the context change                                    
3900         getWindow().getDecorView()                                                                       
3901                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3902     }                                                                                                    
3903                                                                                                          
3904     void enterSpringLoadedDragMode() {                                                                   
3905         if (isAllAppsVisible()) {                                                                        
3906             hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                    
3907             mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                 
3908         }                                                                                                
3909     }                                                                                                    
3910                                                                                                          
3911     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3912             final Runnable onCompleteRunnable) {                                                         
3913         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                        
3914                                                                                                          
3915         mHandler.postDelayed(new Runnable() {                                                            
3916             @Override                                                                                    
3917             public void run() {                                                                          
3918                 if (successfulDrop) {                                                                    
3919                     // Before we show workspace, hide all apps again because                             
3920                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3921                     // clean up our state transition functions                                           
3922                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3923                     showWorkspace(true, onCompleteRunnable);                                             
3924                 } else {                                                                                 
3925                     exitSpringLoadedDragMode();                                                          
3926                 }                                                                                        
3927             }                                                                                            
3928         }, delay);                                                                                       
3929     }                                                                                                    
3930                                                                                                          
3931     void exitSpringLoadedDragMode() {                                                                    
3932         if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3933             final boolean animated = true;                                                               
3934             final boolean springLoaded = true;                                                           
3935             showAppsCustomizeHelper(animated, springLoaded);                                             
3936             mState = State.APPS_CUSTOMIZE;                                                               
3937         }                                                                                                
3938         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3939     }                                                                                                    
3940                                                                                                          
3941     void lockAllApps() {                                                                                 
3942         // TODO                                                                                          
3943     }                                                                                                    
3944                                                                                                          
3945     void unlockAllApps() {                                                                               
3946         // TODO                                                                                          
3947     }                                                                                                    
3948                                                                                                          
3949     /**                                                                                                  
3950      * Hides the hotseat area.                                                                           
3951      */                                                                                                  
3952     void hideHotseat(boolean animated) {                                                                 
3953         if (!LauncherAppState.getInstance().isScreenLarge()) {                                           
3954             if (animated) {                                                                              
3955                 if (mHotseat.getAlpha() != 0f) {                                                         
3956                     int duration = 0;                                                                    
3957                     if (mSearchDropTargetBar != null) {                                                  
3958                         duration = mSearchDropTargetBar.getTransitionOutDuration();                      
3959                     }                                                                                    
3960                     mHotseat.animate().alpha(0f).setDuration(duration);                                  
3961                 }                                                                                        
3962             } else {                                                                                     
3963                 mHotseat.setAlpha(0f);                                                                   
3964             }                                                                                            
3965         }                                                                                                
3966     }                                                                                                    
3967                                                                                                          
3968     /**                                                                                                  
3969      * Add an item from all apps or customize onto the given workspace screen.                           
3970      * If layout is null, add to the current screen.                                                     
3971      */                                                                                                  
3972     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                           
3973         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                     
3974             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
3975         }                                                                                                
3976     }                                                                                                    
3977                                                                                                          
3978     /** Maps the current orientation to an index for referencing orientation correct global icons */     
3979     private int getCurrentOrientationIndexForGlobalIcons() {                                             
3980         // default - 0, landscape - 1                                                                    
3981         switch (getResources().getConfiguration().orientation) {                                         
3982         case Configuration.ORIENTATION_LANDSCAPE:                                                        
3983             return 1;                                                                                    
3984         default:                                                                                         
3985             return 0;                                                                                    
3986         }                                                                                                
3987     }                                                                                                    
3988                                                                                                          
3989     private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {    
3990         try {                                                                                            
3991             PackageManager packageManager = getPackageManager();                                         
3992             // Look for the toolbar icon specified in the activity meta-data                             
3993             Bundle metaData = packageManager.getActivityInfo(                                            
3994                     activityName, PackageManager.GET_META_DATA).metaData;                                
3995             if (metaData != null) {                                                                      
3996                 int iconResId = metaData.getInt(resourceName);                                           
3997                 if (iconResId != 0) {                                                                    
3998                     Resources res = packageManager.getResourcesForActivity(activityName);                
3999                     return res.getDrawable(iconResId);                                                   
4000                 }                                                                                        
4001             }                                                                                            
4002         } catch (NameNotFoundException e) {                                                              
4003             // This can happen if the activity defines an invalid drawable                               
4004             Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +           
4005                     " not found", e);                                                                    
4006         } catch (Resources.NotFoundException nfe) {                                                      
4007             // This can happen if the activity defines an invalid drawable                               
4008             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),        
4009                     nfe);                                                                                
4010         }                                                                                                
4011         return null;                                                                                     
4012     }                                                                                                    
4013                                                                                                          
4014     // if successful in getting icon, return it; otherwise, set button to use default drawable           
4015     private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                         
4016             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
4017             String toolbarResourceName) {                                                                
4018         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
4019         Resources r = getResources();                                                                    
4020         int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                            
4021         int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                           
4022                                                                                                          
4023         TextView button = (TextView) findViewById(buttonId);                                             
4024         // If we were unable to find the icon via the meta-data, use a generic one                       
4025         if (toolbarIcon == null) {                                                                       
4026             toolbarIcon = r.getDrawable(fallbackDrawableId);                                             
4027             toolbarIcon.setBounds(0, 0, w, h);                                                           
4028             if (button != null) {                                                                        
4029                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
4030             }                                                                                            
4031             return null;                                                                                 
4032         } else {                                                                                         
4033             toolbarIcon.setBounds(0, 0, w, h);                                                           
4034             if (button != null) {                                                                        
4035                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
4036             }                                                                                            
4037             return toolbarIcon.getConstantState();                                                       
4038         }                                                                                                
4039     }                                                                                                    
4040                                                                                                          
4041     // if successful in getting icon, return it; otherwise, set button to use default drawable           
4042     private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                             
4043             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
4044             String toolbarResourceName) {                                                                
4045         ImageView button = (ImageView) findViewById(buttonId);                                           
4046         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
4047                                                                                                          
4048         if (button != null) {                                                                            
4049             // If we were unable to find the icon via the meta-data, use a                               
4050             // generic one                                                                               
4051             if (toolbarIcon == null) {                                                                   
4052                 button.setImageResource(fallbackDrawableId);                                             
4053             } else {                                                                                     
4054                 button.setImageDrawable(toolbarIcon);                                                    
4055             }                                                                                            
4056         }                                                                                                
4057                                                                                                          
4058         return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                              
4059                                                                                                          
4060     }                                                                                                    
4061                                                                                                          
4062     private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                
4063         TextView button = (TextView) findViewById(buttonId);                                             
4064         button.setCompoundDrawables(d, null, null, null);                                                
4065     }                                                                                                    
4066                                                                                                          
4067     private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                      
4068         ImageView button = (ImageView) findViewById(buttonId);                                           
4069         button.setImageDrawable(d.newDrawable(getResources()));                                          
4070     }                                                                                                    
4071                                                                                                          
4072     private void invalidatePressedFocusedStates(View container, View button) {                           
4073         if (container instanceof HolographicLinearLayout) {                                              
4074             HolographicLinearLayout layout = (HolographicLinearLayout) container;                        
4075             layout.invalidatePressedFocusedStates();                                                     
4076         } else if (button instanceof HolographicImageView) {                                             
4077             HolographicImageView view = (HolographicImageView) button;                                   
4078             view.invalidatePressedFocusedStates();                                                       
4079         }                                                                                                
4080     }                                                                                                    
4081                                                                                                          
4082     public View getQsbBar() {                                                                            
4083         if (mQsb == null) {                                                                              
4084             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                         
4085             mSearchDropTargetBar.addView(mQsb);                                                          
4086         }                                                                                                
4087         return mQsb;                                                                                     
4088     }                                                                                                    
4089                                                                                                          
4090     protected boolean updateGlobalSearchIcon() {                                                         
4091         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4092         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                     
4093         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4094         final View voiceButton = findViewById(R.id.voice_button);                                        
4095                                                                                                          
4096         final SearchManager searchManager =                                                              
4097                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4098         ComponentName activityName = searchManager.getGlobalSearchActivity();                            
4099         if (activityName != null) {                                                                      
4100             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4101             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                           
4102                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,             
4103                     TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                  
4104             if (sGlobalSearchIcon[coi] == null) {                                                        
4105                 sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                       
4106                         R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,         
4107                         TOOLBAR_ICON_METADATA_NAME);                                                     
4108             }                                                                                            
4109                                                                                                          
4110             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);        
4111             searchButton.setVisibility(View.VISIBLE);                                                    
4112             invalidatePressedFocusedStates(searchButtonContainer, searchButton);                         
4113             return true;                                                                                 
4114         } else {                                                                                         
4115             // We disable both search and voice search when there is no global search provider           
4116             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);           
4117             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4118             if (searchButton != null) searchButton.setVisibility(View.GONE);                             
4119             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4120             updateVoiceButtonProxyVisible(false);                                                        
4121             return false;                                                                                
4122         }                                                                                                
4123     }                                                                                                    
4124                                                                                                          
4125     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                    
4126         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4127         final View searchButton = (ImageView) findViewById(R.id.search_button);                          
4128         updateButtonWithDrawable(R.id.search_button, d);                                                 
4129         invalidatePressedFocusedStates(searchButtonContainer, searchButton);                             
4130     }                                                                                                    
4131                                                                                                          
4132     protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                     
4133         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4134         final View voiceButton = findViewById(R.id.voice_button);                                        
4135                                                                                                          
4136         // We only show/update the voice search icon if the search icon is enabled as well               
4137         final SearchManager searchManager =                                                              
4138                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4139         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
4140                                                                                                          
4141         ComponentName activityName = null;                                                               
4142         if (globalSearchActivity != null) {                                                              
4143             // Check if the global search activity handles voice search                                  
4144             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4145             intent.setPackage(globalSearchActivity.getPackageName());                                    
4146             activityName = intent.resolveActivity(getPackageManager());                                  
4147         }                                                                                                
4148                                                                                                          
4149         if (activityName == null) {                                                                      
4150             // Fallback: check if an activity other than the global search activity                      
4151             // resolves this                                                                             
4152             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4153             activityName = intent.resolveActivity(getPackageManager());                                  
4154         }                                                                                                
4155         if (searchVisible && activityName != null) {                                                     
4156             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4157             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                            
4158                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,               
4159                     TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                            
4160             if (sVoiceSearchIcon[coi] == null) {                                                         
4161                 sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                        
4162                         R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,           
4163                         TOOLBAR_ICON_METADATA_NAME);                                                     
4164             }                                                                                            
4165             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);          
4166             voiceButton.setVisibility(View.VISIBLE);                                                     
4167             updateVoiceButtonProxyVisible(false);                                                        
4168             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                           
4169             return true;                                                                                 
4170         } else {                                                                                         
4171             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4172             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4173             updateVoiceButtonProxyVisible(false);                                                        
4174             return false;                                                                                
4175         }                                                                                                
4176     }                                                                                                    
4177                                                                                                          
4178     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                     
4179         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4180         final View voiceButton = findViewById(R.id.voice_button);                                        
4181         updateButtonWithDrawable(R.id.voice_button, d);                                                  
4182         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                               
4183     }                                                                                                    
4184                                                                                                          
4185     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                    
4186         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                             
4187         if (voiceButtonProxy != null) {                                                                  
4188             boolean visible = !forceDisableVoiceButtonProxy &&                                           
4189                     mWorkspace.shouldVoiceButtonProxyBeVisible();                                        
4190             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                          
4191             voiceButtonProxy.bringToFront();                                                             
4192         }                                                                                                
4193     }                                                                                                    
4194                                                                                                          
4195     /**                                                                                                  
4196      * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button🔵
4197      * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                      
4198      */                                                                                                  
4199     public void disableVoiceButtonProxy(boolean disabled) {                                              
4200         updateVoiceButtonProxyVisible(disabled);                                                         
4201     }                                                                                                    
4202                                                                                                          
4203     @Override                                                                                            
4204     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
4205         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
4206         final List<CharSequence> text = event.getText();                                                 
4207         text.clear();                                                                                    
4208         // Populate event with a fake title based on the current state.                                  
4209         if (mState == State.APPS_CUSTOMIZE) {                                                            
4210             text.add(mAppsCustomizeTabHost.getContentTag());                                             
4211         } else {                                                                                         
4212             text.add(getString(R.string.all_apps_home_button_label));                                    
4213         }                                                                                                
4214         return result;                                                                                   
4215     }                                                                                                    
4216                                                                                                          
4217     /**                                                                                                  
4218      * Receives notifications when system dialogs are to be closed.                                      
4219      */                                                                                                  
4220     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
4221         @Override                                                                                        
4222         public void onReceive(Context context, Intent intent) {                                          
4223             closeSystemDialogs();                                                                        
4224         }                                                                                                
4225     }                                                                                                    
4226                                                                                                          
4227     /**                                                                                                  
4228      * Receives notifications whenever the appwidgets are reset.                                         
4229      */                                                                                                  
4230     private class AppWidgetResetObserver extends ContentObserver {                                       
4231         public AppWidgetResetObserver() {                                                                
4232             super(new Handler());                                                                        
4233         }                                                                                                
4234                                                                                                          
4235         @Override                                                                                        
4236         public void onChange(boolean selfChange) {                                                       
4237             onAppWidgetReset();                                                                          
4238         }                                                                                                
4239     }                                                                                                    
4240                                                                                                          
4241     /**                                                                                                  
4242      * If the activity is currently paused, signal that we need to run the passed Runnable               
4243      * in onResume.                                                                                      
4244      *                                                                                                   
4245      * This needs to be called from incoming places where resources might have been loaded               
4246      * while we are paused.  That is becaues the Configuration might be wrong                            
4247      * when we're not running, and if it comes back to what it was when we                               
4248      * were paused, we are not restarted.                                                                
4249      *                                                                                                   
4250      * Implementation of the method from LauncherModel.Callbacks.                                        
4251      *                                                                                                   
4252      * @return true if we are currently paused.  The caller might be able to                             
4253      * skip some work in that case since we will come back again.                                        
4254      */                                                                                                  
4255     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
4256         if (mPaused) {                                                                                   
4257             Log.i(TAG, "Deferring update until onResume");                                               
4258             if (deletePreviousRunnables) {                                                               
4259                 while (mBindOnResumeCallbacks.remove(run)) {                                             
4260                 }                                                                                        
4261             }                                                                                            
4262             mBindOnResumeCallbacks.add(run);                                                             
4263             return true;                                                                                 
4264         } else {                                                                                         
4265             return false;                                                                                
4266         }                                                                                                
4267     }                                                                                                    
4268                                                                                                          
4269     private boolean waitUntilResume(Runnable run) {                                                      
4270         return waitUntilResume(run, false);                                                              
4271     }                                                                                                    
4272                                                                                                          
4273     public void addOnResumeCallback(Runnable run) {                                                      
4274         mOnResumeCallbacks.add(run);                                                                     
4275     }                                                                                                    
4276                                                                                                          
4277     /**                                                                                                  
4278      * If the activity is currently paused, signal that we need to re-run the loader                     
4279      * in onResume.                                                                                      
4280      *                                                                                                   
4281      * This needs to be called from incoming places where resources might have been loaded               
4282      * while we are paused.  That is becaues the Configuration might be wrong                            
4283      * when we're not running, and if it comes back to what it was when we                               
4284      * were paused, we are not restarted.                                                                
4285      *                                                                                                   
4286      * Implementation of the method from LauncherModel.Callbacks.                                        
4287      *                                                                                                   
4288      * @return true if we are currently paused.  The caller might be able to                             
4289      * skip some work in that case since we will come back again.                                        
4290      */                                                                                                  
4291     public boolean setLoadOnResume() {                                                                   
4292         if (mPaused) {                                                                                   
4293             Log.i(TAG, "setLoadOnResume");                                                               
4294             mOnResumeNeedsLoad = true;                                                                   
4295             return true;                                                                                 
4296         } else {                                                                                         
4297             return false;                                                                                
4298         }                                                                                                
4299     }                                                                                                    
4300                                                                                                          
4301     /**                                                                                                  
4302      * Implementation of the method from LauncherModel.Callbacks.                                        
4303      */                                                                                                  
4304     public int getCurrentWorkspaceScreen() {                                                             
4305         if (mWorkspace != null) {                                                                        
4306             return mWorkspace.getCurrentPage();                                                          
4307         } else {                                                                                         
4308             return SCREEN_COUNT / 2;                                                                     
4309         }                                                                                                
4310     }                                                                                                    
4311                                                                                                          
4312     /**                                                                                                  
4313      * Refreshes the shortcuts shown on the workspace.                                                   
4314      *                                                                                                   
4315      * Implementation of the method from LauncherModel.Callbacks.                                        
4316      */                                                                                                  
4317     public void startBinding() {                                                                         
4318 <<<<<<< GitAnalyzerPlus_ours                                                                             
4319         setWorkspaceLoading(true);                                                                       
4320                                                                                                          
4321 ||||||| GitAnalyzerPlus_base                                                                             
4322      *                                                                                                   
4323      * Implementation of the method from LauncherModel.Callbacks.                                        
4324      */                                                                                                  
4325     public void startBinding() {                                                                         
4326         mWorkspaceLoading = true;                                                                        
4327                                                                                                          
4328         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4329         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4330         // from scratch again                                                                            
4331         mBindOnResumeCallbacks.clear();                                                                  
4332                                                                                                          
4333         // Clear the workspace because it's going to be rebound                                          
4334         mWorkspace.clearDropTargets();                                                                   
4335         mWorkspace.removeAllWorkspaceScreens();                                                          
4336                                                                                                          
4337         mWidgetsToAdvance.clear();                                                                       
4338         if (mHotseat != null) {                                                                          
4339             mHotseat.resetLayout();                                                                      
4340         }                                                                                                
4341     }                                                                                                    
4342                                                                                                          
4343     @Override                                                                                            
4344     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4345         bindAddScreens(orderedScreenIds);                                                                
4346                                                                                                          
4347         // If there are no screens, we need to have an empty screen                                      
4348         if (orderedScreenIds.size() == 0) {                                                              
4349             mWorkspace.addExtraEmptyScreen();                                                            
4350         }                                                                                                
4351                                                                                                          
4352         // Create the custom content page (this call updates mDefaultScreen which calls                  
4353         // setCurrentPage() so ensure that all pages are added before calling this).                     
4354         if (hasCustomContentToLeft()) {                                                                  
4355             mWorkspace.createCustomContentContainer();                                                   
4356             populateCustomContentContainer();                                                            
4357         }                                                                                                
4358     }                                                                                                    
4359                                                                                                          
4360     @Override                                                                                            
4361     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4362         // Log to disk                                                                                   
4363         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4364         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4365                 TextUtils.join(", ", orderedScreenIds), true);                                           
4366         int count = orderedScreenIds.size();                                                             
4367         for (int i = 0; i < count; i++) {                                                                
4368             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4369         }                                                                                                
4370     }                                                                                                    
4371                                                                                                          
4372     private boolean shouldShowWeightWatcher() {                                                          
4373         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4374         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4375         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4376                                                                                                          
4377         return show;                                                                                     
4378     }                                                                                                    
4379                                                                                                          
4380     private void toggleShowWeightWatcher() {                                                             
4381         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4382         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4383         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4384                                                                                                          
4385         show = !show;                                                                                    
4386                                                                                                          
4387         SharedPreferences.Editor editor = sp.edit();                                                     
4388         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4389         editor.commit();                                                                                 
4390                                                                                                          
4391         if (mWeightWatcher != null) {                                                                    
4392             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4393         }                                                                                                
4394     }                                                                                                    
4395                                                                                                          
4396     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4397                               final ArrayList<ItemInfo> addNotAnimated,                                  
4398                               final ArrayList<ItemInfo> addAnimated,                                     
4399                               final ArrayList<AppInfo> addedApps) {                                      
4400         Runnable r = new Runnable() {                                                                    
4401             public void run() {                                                                          
4402                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4403             }                                                                                            
4404         };                                                                                               
4405         if (waitUntilResume(r)) {                                                                        
4406             return;                                                                                      
4407         }                                                                                                
4408                                                                                                          
4409         // Add the new screens                                                                           
4410         bindAddScreens(newScreens);                                                                      
4411                                                                                                          
4412         // We add the items without animation on non-visible pages, and with                             
4413         // animations on the new page (which we will try and snap to).                                   
4414         if (!addNotAnimated.isEmpty()) {                                                                 
4415             bindItems(addNotAnimated, 0,                                                                 
4416                     addNotAnimated.size(), false);                                                       
4417         }                                                                                                
4418         if (!addAnimated.isEmpty()) {                                                                    
4419             bindItems(addAnimated, 0,                                                                    
4420                     addAnimated.size(), true);                                                           
4421         }                                                                                                
4422                                                                                                          
4423         // Remove the extra empty screen                                                                 
4424         mWorkspace.removeExtraEmptyScreen(false, null);                                                  
4425                                                                                                          
4426         if (!LauncherAppState.isDisableAllApps() &&                                                      
4427                 addedApps != null && mAppsCustomizeContent != null) {                                    
4428             mAppsCustomizeContent.addApps(addedApps);                                                    
4429         }                                                                                                
4430     }                                                                                                    
4431                                                                                                          
4432     /**                                                                                                  
4433      * Bind the items start-end from the list.                                                           
4434      *                                                                                                   
4435      * Implementation of the method from LauncherModel.Callbacks.                                        
4436      */                                                                                                  
4437     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4438                           final boolean forceAnimateIcons) {                                             
4439         Runnable r = new Runnable() {                                                                    
4440             public void run() {                                                                          
4441                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4442             }                                                                                            
4443         };                                                                                               
4444         if (waitUntilResume(r)) {                                                                        
4445             return;                                                                                      
4446         }                                                                                                
4447                                                                                                          
4448         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4449         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4450         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4451         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4452         Workspace workspace = mWorkspace;                                                                
4453         long newShortcutsScreenId = -1;                                                                  
4454         for (int i = start; i < end; i++) {                                                              
4455             final ItemInfo item = shortcuts.get(i);                                                      
4456                                                                                                          
4457             // Short circuit if we are loading dock items for a configuration which has no dock          
4458             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4459                     mHotseat == null) {                                                                  
4460                 continue;                                                                                
4461             }                                                                                            
4462                                                                                                          
4463             switch (item.itemType) {                                                                     
4464                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4465                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4466                     ShortcutInfo info = (ShortcutInfo) item;                                             
4467                     View shortcut = createShortcut(info);                                                
4468                                                                                                          
4469                     /*                                                                                   
4470                      * TODO: FIX collision case                                                          
4471                      */                                                                                  
4472                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4473                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4474                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4475                             throw new RuntimeException("OCCUPIED");                                      
4476                         }                                                                                
4477                     }                                                                                    
4478                                                                                                          
4479                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4480                             item.cellY, 1, 1);                                                           
4481                     if (animateIcons) {                                                                  
4482                         // Animate all the applications up now                                           
4483                         shortcut.setAlpha(0f);                                                           
4484                         shortcut.setScaleX(0f);                                                          
4485                         shortcut.setScaleY(0f);                                                          
4486                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4487                         newShortcutsScreenId = item.screenId;                                            
4488                     }                                                                                    
4489                     break;                                                                               
4490                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4491                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4492                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4493                             (FolderInfo) item, mIconCache);                                              
4494                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4495                             item.cellY, 1, 1);                                                           
4496                     break;                                                                               
4497                 default:                                                                                 
4498                     throw new RuntimeException("Invalid Item Type");                                     
4499             }                                                                                            
4500         }                                                                                                
4501                                                                                                          
4502         if (animateIcons) {                                                                              
4503             // Animate to the correct page                                                               
4504             if (newShortcutsScreenId > -1) {                                                             
4505                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4506                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4507                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4508                     public void run() {                                                                  
4509                         anim.playTogether(bounceAnims);                                                  
4510                         anim.start();                                                                    
4511                     }                                                                                    
4512                 };                                                                                       
4513                 if (newShortcutsScreenId != currentScreenId) {                                           
4514                     // We post the animation slightly delayed to prevent slowdowns                       
4515                     // when we are loading right after we return to launcher.                            
4516                     mWorkspace.postDelayed(new Runnable() {                                              
4517                         public void run() {                                                              
4518                             if (mWorkspace != null) {                                                    
4519                                 mWorkspace.snapToPage(newScreenIndex);                                   
4520                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4521                                         NEW_APPS_ANIMATION_DELAY);                                       
4522                             }                                                                            
4523                         }                                                                                
4524                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4525                 } else {                                                                                 
4526                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4527                 }                                                                                        
4528             }                                                                                            
4529         }                                                                                                
4530         workspace.requestLayout();                                                                       
4531     }                                                                                                    
4532                                                                                                          
4533     /**                                                                                                  
4534      * Implementation of the method from LauncherModel.Callbacks.                                        
4535      */                                                                                                  
4536     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4537         Runnable r = new Runnable() {                                                                    
4538             public void run() {                                                                          
4539                 bindFolders(folders);                                                                    
4540             }                                                                                            
4541         };                                                                                               
4542         if (waitUntilResume(r)) {                                                                        
4543             return;                                                                                      
4544         }                                                                                                
4545         sFolders.clear();                                                                                
4546         sFolders.putAll(folders);                                                                        
4547     }                                                                                                    
4548                                                                                                          
4549     /**                                                                                                  
4550      * Add the views for a widget to the workspace.                                                      
4551      *                                                                                                   
4552      * Implementation of the method from LauncherModel.Callbacks.                                        
4553      */                                                                                                  
4554     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4555         Runnable r = new Runnable() {                                                                    
4556             public void run() {                                                                          
4557                 bindAppWidget(item);                                                                     
4558             }                                                                                            
4559         };                                                                                               
4560         if (waitUntilResume(r)) {                                                                        
4561             return;                                                                                      
4562         }                                                                                                
4563                                                                                                          
4564         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4565         if (DEBUG_WIDGETS) {                                                                             
4566             Log.d(TAG, "bindAppWidget: " + item);                                                        
4567         }                                                                                                
4568         final Workspace workspace = mWorkspace;                                                          
4569                                                                                                          
4570         final int appWidgetId = item.appWidgetId;                                                        
4571         final AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);     
4572         if (DEBUG_WIDGETS) {                                                                             
4573             Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidgetInfo🔵
4574         }                                                                                                
4575                                                                                                          
4576         item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                     
4577                                                                                                          
4578         item.hostView.setTag(item);                                                                      
4579         item.onBindAppWidget(this);                                                                      
4580                                                                                                          
4581         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4582                 item.cellY, item.spanX, item.spanY, false);                                              
4583         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
4584                                                                                                          
4585         workspace.requestLayout();                                                                       
4586                                                                                                          
4587         if (DEBUG_WIDGETS) {                                                                             
4588             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4589                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4590         }                                                                                                
4591     }                                                                                                    
4592                                                                                                          
4593     public void onPageBoundSynchronously(int page) {                                                     
4594         mSynchronouslyBoundPages.add(page);                                                              
4595     }                                                                                                    
4596                                                                                                          
4597     /**                                                                                                  
4598      * Callback saying that there aren't any more items to bind.                                         
4599      *                                                                                                   
4600      * Implementation of the method from LauncherModel.Callbacks.                                        
4601      */                                                                                                  
4602     public void finishBindingItems(final boolean upgradePath) {                                          
4603         Runnable r = new Runnable() {                                                                    
4604             public void run() {                                                                          
4605                 finishBindingItems(upgradePath);                                                         
4606             }                                                                                            
4607         };                                                                                               
4608         if (waitUntilResume(r)) {                                                                        
4609             return;                                                                                      
4610         }                                                                                                
4611         if (mSavedState != null) {                                                                       
4612             if (!mWorkspace.hasFocus()) {                                                                
4613                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4614             }                                                                                            
4615             mSavedState = null;                                                                          
4616         }                                                                                                
4617                                                                                                          
4618         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4619                                                                                                          
4620         // If we received the result of any pending adds while the loader was running (e.g. the          
4621         // widget configuration forced an orientation change), process them now.                         
4622         for (int i = 0; i < sPendingAddList.size(); i++) {                                               
4623             completeAdd(sPendingAddList.get(i));                                                         
4624         }                                                                                                
4625         sPendingAddList.clear();                                                                         
4626                                                                                                          
4627         // Update the market app icon as necessary (the other icons will be managed in response to       
4628         // package changes in bindSearchablesChanged()                                                   
4629         if (!DISABLE_MARKET_BUTTON) {                                                                    
4630             updateAppMarketIcon();                                                                       
4631         }                                                                                                
4632                                                                                                          
4633         mWorkspaceLoading = false;                                                                       
4634         if (upgradePath) {                                                                               
4635             mWorkspace.getUniqueComponents(true, null);                                                  
4636             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4637         }                                                                                                
4638     }                                                                                                    
4639                                                                                                          
4640     public boolean isAllAppsButtonRank(int rank) {                                                       
4641         if (mHotseat != null) {                                                                          
4642             return mHotseat.isAllAppsButtonRank(rank);                                                   
4643         }                                                                                                
4644         return false;                                                                                    
4645     }                                                                                                    
4646                                                                                                          
4647     private boolean canRunNewAppsAnimation() {                                                           
4648         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4649         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4650     }                                                                                                    
4651                                                                                                          
4652     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4653         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4654                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4655                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4656                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4657         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4658         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4659         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4660         return bounceAnim;                                                                               
4661     }                                                                                                    
4662                                                                                                          
4663     public boolean useVerticalBarLayout() {                                                              
4664         return LauncherAppState.getInstance().getDynamicGrid().                                          
4665                 getDeviceProfile().isVerticalBarLayout();                                                
4666     }                                                                                                    
4667                                                                                                          
4668     protected Rect getSearchBarBounds() {                                                                
4669         return LauncherAppState.getInstance().getDynamicGrid().                                          
4670                 getDeviceProfile().getSearchBarBounds();                                                 
4671     }                                                                                                    
4672                                                                                                          
4673     @Override                                                                                            
4674     public void bindSearchablesChanged() {                                                               
4675         boolean searchVisible = updateGlobalSearchIcon();                                                
4676         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
4677         if (mSearchDropTargetBar != null) {                                                              
4678             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
4679         }                                                                                                
4680     }                                                                                                    
4681                                                                                                          
4682     /**                                                                                                  
4683      * Add the icons for all apps.                                                                       
4684      *                                                                                                   
4685      * Implementation of the method from LauncherModel.Callbacks.                                        
4686      */                                                                                                  
4687     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4688         if (LauncherAppState.isDisableAllApps()) {                                                       
4689             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4690                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4691                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4692                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4693                 }                                                                                        
4694                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4695             }                                                                                            
4696             if (mAppsCustomizeContent != null) {                                                         
4697                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4698                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4699             }                                                                                            
4700         } else {                                                                                         
4701             if (mAppsCustomizeContent != null) {                                                         
4702                 mAppsCustomizeContent.setApps(apps);                                                     
4703                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4704                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4705             }                                                                                            
4706         }                                                                                                
4707     }                                                                                                    
4708                                                                                                          
4709     /**                                                                                                  
4710      * A package was updated.                                                                            
4711      *                                                                                                   
4712      * Implementation of the method from LauncherModel.Callbacks.                                        
4713      */                                                                                                  
4714     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4715         Runnable r = new Runnable() {                                                                    
4716             public void run() {                                                                          
4717                 bindAppsUpdated(apps);                                                                   
4718             }                                                                                            
4719         };                                                                                               
4720         if (waitUntilResume(r)) {                                                                        
4721             return;                                                                                      
4722         }                                                                                                
4723                                                                                                          
4724         if (mWorkspace != null) {                                                                        
4725             mWorkspace.updateShortcuts(apps);                                                            
4726         }                                                                                                
4727                                                                                                          
4728         if (!LauncherAppState.isDisableAllApps() &&                                                      
4729                 mAppsCustomizeContent != null) {                                                         
4730             mAppsCustomizeContent.updateApps(apps);                                                      
4731         }                                                                                                
4732     }                                                                                                    
4733                                                                                                          
4734     /**                                                                                                  
4735      * A package was uninstalled.  We take both the super set of packageNames                            
4736      * in addition to specific applications to remove, the reason being that                             
4737      * this can be called when a package is updated as well.  In that scenario,                          
4738      * we only remove specific components from the workspace, where as                                   
4739      * package-removal should clear all items by package name.                                           
4740      *                                                                                                   
4741      * Implementation of the method from LauncherModel.Callbacks.                                        
4742      */                                                                                                  
4743     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4744                                       final ArrayList<AppInfo> appInfos) {                               
4745         Runnable r = new Runnable() {                                                                    
4746             public void run() {                                                                          
4747                 bindComponentsRemoved(packageNames, appInfos);                                           
4748             }                                                                                            
4749         };                                                                                               
4750         if (waitUntilResume(r)) {                                                                        
4751             return;                                                                                      
4752         }                                                                                                
4753 =======                                                                                                  
4754 >>>>>>> GitAnalyzerPlus_theirs                                                                           
4755         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4756         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4757         // from scratch again                                                                            
4758         mBindOnResumeCallbacks.clear();                                                                  
4759                                                                                                          
4760         // Clear the workspace because it's going to be rebound                                          
4761         mWorkspace.clearDropTargets();                                                                   
4762         mWorkspace.removeAllWorkspaceScreens();                                                          
4763                                                                                                          
4764         mWidgetsToAdvance.clear();                                                                       
4765         if (mHotseat != null) {                                                                          
4766             mHotseat.resetLayout();                                                                      
4767         }                                                                                                
4768     }                                                                                                    
4769                                                                                                          
4770     @Override                                                                                            
4771     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4772         bindAddScreens(orderedScreenIds);                                                                
4773                                                                                                          
4774         // If there are no screens, we need to have an empty screen                                      
4775         if (orderedScreenIds.size() == 0) {                                                              
4776             mWorkspace.addExtraEmptyScreen();                                                            
4777         }                                                                                                
4778                                                                                                          
4779         // Create the custom content page (this call updates mDefaultScreen which calls                  
4780         // setCurrentPage() so ensure that all pages are added before calling this).                     
4781         if (hasCustomContentToLeft()) {                                                                  
4782             mWorkspace.createCustomContentContainer();                                                   
4783             populateCustomContentContainer();                                                            
4784         }                                                                                                
4785     }                                                                                                    
4786                                                                                                          
4787     @Override                                                                                            
4788     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4789         // Log to disk                                                                                   
4790         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4791         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4792                 TextUtils.join(", ", orderedScreenIds), true);                                           
4793         int count = orderedScreenIds.size();                                                             
4794         for (int i = 0; i < count; i++) {                                                                
4795             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4796         }                                                                                                
4797     }                                                                                                    
4798                                                                                                          
4799     private boolean shouldShowWeightWatcher() {                                                          
4800         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4801         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4802         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4803                                                                                                          
4804         return show;                                                                                     
4805     }                                                                                                    
4806                                                                                                          
4807     private void toggleShowWeightWatcher() {                                                             
4808         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4809         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4810         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4811                                                                                                          
4812         show = !show;                                                                                    
4813                                                                                                          
4814         SharedPreferences.Editor editor = sp.edit();                                                     
4815         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4816         editor.commit();                                                                                 
4817                                                                                                          
4818         if (mWeightWatcher != null) {                                                                    
4819             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4820         }                                                                                                
4821     }                                                                                                    
4822                                                                                                          
4823     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4824                               final ArrayList<ItemInfo> addNotAnimated,                                  
4825                               final ArrayList<ItemInfo> addAnimated,                                     
4826                               final ArrayList<AppInfo> addedApps) {                                      
4827         Runnable r = new Runnable() {                                                                    
4828             public void run() {                                                                          
4829                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4830             }                                                                                            
4831         };                                                                                               
4832         if (waitUntilResume(r)) {                                                                        
4833             return;                                                                                      
4834         }                                                                                                
4835                                                                                                          
4836         // Add the new screens                                                                           
4837         if (newScreens != null) {                                                                        
4838             bindAddScreens(newScreens);                                                                  
4839         }                                                                                                
4840                                                                                                          
4841         // We add the items without animation on non-visible pages, and with                             
4842         // animations on the new page (which we will try and snap to).                                   
4843         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
4844             bindItems(addNotAnimated, 0,                                                                 
4845                     addNotAnimated.size(), false);                                                       
4846         }                                                                                                
4847         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
4848             bindItems(addAnimated, 0,                                                                    
4849                     addAnimated.size(), true);                                                           
4850         }                                                                                                
4851                                                                                                          
4852         // Remove the extra empty screen                                                                 
4853         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4854                                                                                                          
4855         if (!LauncherAppState.isDisableAllApps() &&                                                      
4856                 addedApps != null && mAppsCustomizeContent != null) {                                    
4857             mAppsCustomizeContent.addApps(addedApps);                                                    
4858         }                                                                                                
4859     }                                                                                                    
4860                                                                                                          
4861     /**                                                                                                  
4862      * Bind the items start-end from the list.                                                           
4863      *                                                                                                   
4864      * Implementation of the method from LauncherModel.Callbacks.                                        
4865      */                                                                                                  
4866     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4867                           final boolean forceAnimateIcons) {                                             
4868         Runnable r = new Runnable() {                                                                    
4869             public void run() {                                                                          
4870                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4871             }                                                                                            
4872         };                                                                                               
4873         if (waitUntilResume(r)) {                                                                        
4874             return;                                                                                      
4875         }                                                                                                
4876                                                                                                          
4877         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4878         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4879         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4880         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4881         Workspace workspace = mWorkspace;                                                                
4882         long newShortcutsScreenId = -1;                                                                  
4883         for (int i = start; i < end; i++) {                                                              
4884             final ItemInfo item = shortcuts.get(i);                                                      
4885                                                                                                          
4886             // Short circuit if we are loading dock items for a configuration which has no dock          
4887             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4888                     mHotseat == null) {                                                                  
4889                 continue;                                                                                
4890             }                                                                                            
4891                                                                                                          
4892             switch (item.itemType) {                                                                     
4893                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4894                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4895                     ShortcutInfo info = (ShortcutInfo) item;                                             
4896                     View shortcut = createShortcut(info);                                                
4897                                                                                                          
4898                     /*                                                                                   
4899                      * TODO: FIX collision case                                                          
4900                      */                                                                                  
4901                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4902                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4903                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4904                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4905                             Object tag = v.getTag();                                                     
4906                             String desc = "Collision while binding workspace item: " + item              
4907                                     + ". Collides with " + tag;                                          
4908                             if (LauncherAppState.isDogfoodBuild()) {                                     
4909                                 throw (new RuntimeException(desc));                                      
4910                             } else {                                                                     
4911                                 Log.d(TAG, desc);                                                        
4912                             }                                                                            
4913                         }                                                                                
4914                     }                                                                                    
4915                                                                                                          
4916                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4917                             item.cellY, 1, 1);                                                           
4918                     if (animateIcons) {                                                                  
4919                         // Animate all the applications up now                                           
4920                         shortcut.setAlpha(0f);                                                           
4921                         shortcut.setScaleX(0f);                                                          
4922                         shortcut.setScaleY(0f);                                                          
4923                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4924                         newShortcutsScreenId = item.screenId;                                            
4925                     }                                                                                    
4926                     break;                                                                               
4927                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4928                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4929                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4930                             (FolderInfo) item, mIconCache);                                              
4931                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4932                             item.cellY, 1, 1);                                                           
4933                     break;                                                                               
4934                 default:                                                                                 
4935                     throw new RuntimeException("Invalid Item Type");                                     
4936             }                                                                                            
4937         }                                                                                                
4938                                                                                                          
4939         if (animateIcons) {                                                                              
4940             // Animate to the correct page                                                               
4941             if (newShortcutsScreenId > -1) {                                                             
4942                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4943                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4944                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4945                     public void run() {                                                                  
4946                         anim.playTogether(bounceAnims);                                                  
4947                         anim.start();                                                                    
4948                     }                                                                                    
4949                 };                                                                                       
4950                 if (newShortcutsScreenId != currentScreenId) {                                           
4951                     // We post the animation slightly delayed to prevent slowdowns                       
4952                     // when we are loading right after we return to launcher.                            
4953                     mWorkspace.postDelayed(new Runnable() {                                              
4954                         public void run() {                                                              
4955                             if (mWorkspace != null) {                                                    
4956                                 mWorkspace.snapToPage(newScreenIndex);                                   
4957                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4958                                         NEW_APPS_ANIMATION_DELAY);                                       
4959                             }                                                                            
4960                         }                                                                                
4961                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4962                 } else {                                                                                 
4963                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4964                 }                                                                                        
4965             }                                                                                            
4966         }                                                                                                
4967         workspace.requestLayout();                                                                       
4968     }                                                                                                    
4969                                                                                                          
4970     /**                                                                                                  
4971      * Implementation of the method from LauncherModel.Callbacks.                                        
4972      */                                                                                                  
4973     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4974         Runnable r = new Runnable() {                                                                    
4975             public void run() {                                                                          
4976                 bindFolders(folders);                                                                    
4977             }                                                                                            
4978         };                                                                                               
4979         if (waitUntilResume(r)) {                                                                        
4980             return;                                                                                      
4981         }                                                                                                
4982         sFolders.clear();                                                                                
4983         sFolders.putAll(folders);                                                                        
4984     }                                                                                                    
4985                                                                                                          
4986     /**                                                                                                  
4987      * Add the views for a widget to the workspace.                                                      
4988      *                                                                                                   
4989      * Implementation of the method from LauncherModel.Callbacks.                                        
4990      */                                                                                                  
4991     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4992         Runnable r = new Runnable() {                                                                    
4993             public void run() {                                                                          
4994                 bindAppWidget(item);                                                                     
4995             }                                                                                            
4996         };                                                                                               
4997         if (waitUntilResume(r)) {                                                                        
4998             return;                                                                                      
4999         }                                                                                                
5000                                                                                                          
5001         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
5002         if (DEBUG_WIDGETS) {                                                                             
5003             Log.d(TAG, "bindAppWidget: " + item);                                                        
5004         }                                                                                                
5005         final Workspace workspace = mWorkspace;                                                          
5006                                                                                                          
5007         AppWidgetProviderInfo appWidgetInfo;                                                             
5008         if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&               
5009                 ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                 
5010                                                                                                          
5011             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);      
5012             if (appWidgetInfo == null) {                                                                 
5013                 if (DEBUG_WIDGETS) {                                                                     
5014                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
5015                             + " belongs to component " + item.providerName                               
5016                             + ", as the povider is null");                                               
5017                 }                                                                                        
5018                 LauncherModel.deleteItemFromDatabase(this, item);                                        
5019                 return;                                                                                  
5020             }                                                                                            
5021             // Note: This assumes that the id remap broadcast is received before this step.              
5022             // If that is not the case, the id remap will be ignored and user may see the                
5023             // click to setup view.                                                                      
5024             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);      
5025             pendingInfo.spanX = item.spanX;                                                              
5026             pendingInfo.spanY = item.spanY;                                                              
5027             pendingInfo.minSpanX = item.minSpanX;                                                        
5028             pendingInfo.minSpanY = item.minSpanY;                                                        
5029             Bundle options =                                                                             
5030                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
5031                                                                                                          
5032             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
5033             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
5034                     newWidgetId, appWidgetInfo, options);                                                
5035                                                                                                          
5036             // TODO consider showing a permission dialog when the widget is clicked.                     
5037             if (!success) {                                                                              
5038                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
5039                 if (DEBUG_WIDGETS) {                                                                     
5040                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
5041                             + " belongs to component " + item.providerName                               
5042                             + ", as the launcher is unable to bing a new widget id");                    
5043                 }                                                                                        
5044                 LauncherModel.deleteItemFromDatabase(this, item);                                        
5045                 return;                                                                                  
5046             }                                                                                            
5047                                                                                                          
5048             item.appWidgetId = newWidgetId;                                                              
5049                                                                                                          
5050             // If the widget has a configure activity, it is still needs to set it up, otherwise         
5051             // the widget is ready to go.                                                                
5052             item.restoreStatus = (appWidgetInfo.configure == null)                                       
5053                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
5054                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
5055                                                                                                          
5056             LauncherModel.updateItemInDatabase(this, item);                                              
5057         }                                                                                                
5058                                                                                                          
5059         if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                             
5060             final int appWidgetId = item.appWidgetId;                                                    
5061             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
5062             if (DEBUG_WIDGETS) {                                                                         
5063                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidget🔵
5064             }                                                                                            
5065                                                                                                          
5066             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
5067         } else {                                                                                         
5068             appWidgetInfo = null;                                                                        
5069             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                    
5070             view.updateIcon(mIconCache);                                                                 
5071             item.hostView = view;                                                                        
5072             item.hostView.updateAppWidget(null);                                                         
5073             item.hostView.setOnClickListener(this);                                                      
5074         }                                                                                                
5075                                                                                                          
5076         item.hostView.setTag(item);                                                                      
5077         item.onBindAppWidget(this);                                                                      
5078                                                                                                          
5079         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
5080                 item.cellY, item.spanX, item.spanY, false);                                              
5081         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
5082                                                                                                          
5083         workspace.requestLayout();                                                                       
5084                                                                                                          
5085         if (DEBUG_WIDGETS) {                                                                             
5086             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
5087                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
5088         }                                                                                                
5089     }                                                                                                    
5090                                                                                                          
5091     /**                                                                                                  
5092      * Restores a pending widget.                                                                        
5093      *                                                                                                   
5094      * @param appWidgetId The app widget id                                                              
5095      * @param cellInfo The position on screen where to create the widget.                                
5096      */                                                                                                  
5097     private void completeRestoreAppWidget(final int appWidgetId) {                                       
5098         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
5099         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
5100             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
5101             return;                                                                                      
5102         }                                                                                                
5103                                                                                                          
5104         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
5105         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
5106                                                                                                          
5107         mWorkspace.reinflateWidgetsIfNecessary();                                                        
5108         LauncherModel.updateItemInDatabase(this, info);                                                  
5109     }                                                                                                    
5110                                                                                                          
5111     public void onPageBoundSynchronously(int page) {                                                     
5112         mSynchronouslyBoundPages.add(page);                                                              
5113     }                                                                                                    
5114                                                                                                          
5115     /**                                                                                                  
5116      * Callback saying that there aren't any more items to bind.                                         
5117      *                                                                                                   
5118      * Implementation of the method from LauncherModel.Callbacks.                                        
5119      */                                                                                                  
5120     public void finishBindingItems(final boolean upgradePath) {                                          
5121         Runnable r = new Runnable() {                                                                    
5122             public void run() {                                                                          
5123                 finishBindingItems(upgradePath);                                                         
5124             }                                                                                            
5125         };                                                                                               
5126         if (waitUntilResume(r)) {                                                                        
5127             return;                                                                                      
5128         }                                                                                                
5129         if (mSavedState != null) {                                                                       
5130             if (!mWorkspace.hasFocus()) {                                                                
5131                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
5132             }                                                                                            
5133             mSavedState = null;                                                                          
5134         }                                                                                                
5135                                                                                                          
5136         mWorkspace.restoreInstanceStateForRemainingPages();                                              
5137                                                                                                          
5138         setWorkspaceLoading(false);                                                                      
5139         sendLoadingCompleteBroadcastIfNecessary();                                                       
5140                                                                                                          
5141         // If we received the result of any pending adds while the loader was running (e.g. the          
5142         // widget configuration forced an orientation change), process them now.                         
5143         if (sPendingAddItem != null) {                                                                   
5144             final long screenId = completeAdd(sPendingAddItem);                                          
5145                                                                                                          
5146             // TODO: this moves the user to the page where the pending item was added. Ideally,          
5147             // the screen would be guaranteed to exist after bind, and the page would be set through     
5148             // the workspace restore process.                                                            
5149             mWorkspace.post(new Runnable() {                                                             
5150                 @Override                                                                                
5151                 public void run() {                                                                      
5152                     mWorkspace.snapToScreenId(screenId);                                                 
5153                 }                                                                                        
5154             });                                                                                          
5155             sPendingAddItem = null;                                                                      
5156         }                                                                                                
5157                                                                                                          
5158         if (upgradePath) {                                                                               
5159             mWorkspace.getUniqueComponents(true, null);                                                  
5160             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
5161         }                                                                                                
5162         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
5163         mModel.recheckRestoredItems(this);                                                               
5164     }                                                                                                    
5165                                                                                                          
5166     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
5167         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
5168             String permission =                                                                          
5169                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
5170             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
5171             sendBroadcast(intent, permission);                                                           
5172             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
5173             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
5174             editor.apply();                                                                              
5175         }                                                                                                
5176     }                                                                                                    
5177                                                                                                          
5178     public boolean isAllAppsButtonRank(int rank) {                                                       
5179         if (mHotseat != null) {                                                                          
5180             return mHotseat.isAllAppsButtonRank(rank);                                                   
5181         }                                                                                                
5182         return false;                                                                                    
5183     }                                                                                                    
5184                                                                                                          
5185     private boolean canRunNewAppsAnimation() {                                                           
5186         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
5187         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
5188     }                                                                                                    
5189                                                                                                          
5190     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
5191         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
5192                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
5193                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
5194                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
5195         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
5196         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
5197         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
5198         return bounceAnim;                                                                               
5199     }                                                                                                    
5200                                                                                                          
5201     public boolean useVerticalBarLayout() {                                                              
5202         return LauncherAppState.getInstance().getDynamicGrid().                                          
5203                 getDeviceProfile().isVerticalBarLayout();                                                
5204     }                                                                                                    
5205                                                                                                          
5206     protected Rect getSearchBarBounds() {                                                                
5207         return LauncherAppState.getInstance().getDynamicGrid().                                          
5208                 getDeviceProfile().getSearchBarBounds();                                                 
5209     }                                                                                                    
5210                                                                                                          
5211     @Override                                                                                            
5212     public void bindSearchablesChanged() {                                                               
5213         boolean searchVisible = updateGlobalSearchIcon();                                                
5214         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
5215         if (mSearchDropTargetBar != null) {                                                              
5216             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
5217         }                                                                                                
5218     }                                                                                                    
5219                                                                                                          
5220     /**                                                                                                  
5221      * Add the icons for all apps.                                                                       
5222      *                                                                                                   
5223      * Implementation of the method from LauncherModel.Callbacks.                                        
5224      */                                                                                                  
5225     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
5226         if (LauncherAppState.isDisableAllApps()) {                                                       
5227             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
5228                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
5229                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
5230                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
5231                 }                                                                                        
5232                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
5233             }                                                                                            
5234             if (mAppsCustomizeContent != null) {                                                         
5235                 mAppsCustomizeContent.onPackagesUpdated(                                                 
5236                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
5237             }                                                                                            
5238         } else {                                                                                         
5239             if (mAppsCustomizeContent != null) {                                                         
5240                 mAppsCustomizeContent.setApps(apps);                                                     
5241                 mAppsCustomizeContent.onPackagesUpdated(                                                 
5242                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
5243             }                                                                                            
5244         }                                                                                                
5245     }                                                                                                    
5246                                                                                                          
5247     /**                                                                                                  
5248      * A package was updated.                                                                            
5249      *                                                                                                   
5250      * Implementation of the method from LauncherModel.Callbacks.                                        
5251      */                                                                                                  
5252     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
5253         Runnable r = new Runnable() {                                                                    
5254             public void run() {                                                                          
5255                 bindAppsUpdated(apps);                                                                   
5256             }                                                                                            
5257         };                                                                                               
5258         if (waitUntilResume(r)) {                                                                        
5259             return;                                                                                      
5260         }                                                                                                
5261                                                                                                          
5262         if (mWorkspace != null) {                                                                        
5263             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
5264         }                                                                                                
5265                                                                                                          
5266         if (!LauncherAppState.isDisableAllApps() &&                                                      
5267                 mAppsCustomizeContent != null) {                                                         
5268             mAppsCustomizeContent.updateApps(apps);                                                      
5269         }                                                                                                
5270     }                                                                                                    
5271                                                                                                          
5272     /**                                                                                                  
5273      * Packages were restored                                                                            
5274      */                                                                                                  
5275     public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                        
5276         Runnable r = new Runnable() {                                                                    
5277             public void run() {                                                                          
5278                 bindAppsRestored(apps);                                                                  
5279             }                                                                                            
5280         };                                                                                               
5281         if (waitUntilResume(r)) {                                                                        
5282             return;                                                                                      
5283         }                                                                                                
5284                                                                                                          
5285         if (mWorkspace != null) {                                                                        
5286             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
5287         }                                                                                                
5288     }                                                                                                    
5289                                                                                                          
5290     /**                                                                                                  
5291      * Update the state of a package, typically related to install state.                                
5292      *                                                                                                   
5293      * Implementation of the method from LauncherModel.Callbacks.                                        
5294      */                                                                                                  
5295     @Override                                                                                            
5296     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
5297         if (mWorkspace != null) {                                                                        
5298             mWorkspace.updatePackageState(installInfo);                                                  
5299         }                                                                                                
5300     }                                                                                                    
5301                                                                                                          
5302     /**                                                                                                  
5303      * Update the label and icon of all the icons in a package                                           
5304      *                                                                                                   
5305      * Implementation of the method from LauncherModel.Callbacks.                                        
5306      */                                                                                                  
5307     @Override                                                                                            
5308     public void updatePackageBadge(String packageName) {                                                 
5309         if (mWorkspace != null) {                                                                        
5310             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
5311         }                                                                                                
5312     }                                                                                                    
5313                                                                                                          
5314     /**                                                                                                  
5315      * A package was uninstalled.  We take both the super set of packageNames                            
5316      * in addition to specific applications to remove, the reason being that                             
5317      * this can be called when a package is updated as well.  In that scenario,                          
5318      * we only remove specific components from the workspace, where as                                   
5319      * package-removal should clear all items by package name.                                           
5320      *                                                                                                   
5321      * Implementation of the method from LauncherModel.Callbacks.                                        
5322      */                                                                                                  
5323     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
5324             final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {                            
5325         Runnable r = new Runnable() {                                                                    
5326             public void run() {                                                                          
5327                 bindComponentsRemoved(packageNames, appInfos, user);                                     
5328             }                                                                                            
5329         };                                                                                               
5330         if (waitUntilResume(r)) {                                                                        
5331             return;                                                                                      
5332         }                                                                                                
5333                                                                                                          
5334         if (!packageNames.isEmpty()) {                                                                   
5335             mWorkspace.removeItemsByPackageName(packageNames, user);                                     
5336         }                                                                                                
5337         if (!appInfos.isEmpty()) {                                                                       
5338             mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                     
5339         }                                                                                                
5340                                                                                                          
5341         // Notify the drag controller                                                                    
5342         mDragController.onAppsRemoved(packageNames, appInfos);                                           
5343                                                                                                          
5344         // Update AllApps                                                                                
5345         if (!LauncherAppState.isDisableAllApps() &&                                                      
5346                 mAppsCustomizeContent != null) {                                                         
5347             mAppsCustomizeContent.removeApps(appInfos);                                                  
5348         }                                                                                                
5349     }                                                                                                    
5350                                                                                                          
5351     /**                                                                                                  
5352      * A number of packages were updated.                                                                
5353      */                                                                                                  
5354     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
5355     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
5356             public void run() {                                                                          
5357                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
5358                 mWidgetsAndShortcuts = null;                                                             
5359             }                                                                                            
5360         };                                                                                               
5361     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
5362         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
5363             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
5364             return;                                                                                      
5365         }                                                                                                
5366                                                                                                          
5367         // Update the widgets pane                                                                       
5368         if (mAppsCustomizeContent != null) {                                                             
5369             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
5370         }                                                                                                
5371     }                                                                                                    
5372                                                                                                          
5373     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
5374         final Display d = getWindowManager().getDefaultDisplay();                                        
5375         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
5376         switch (d.getRotation()) {                                                                       
5377         case Surface.ROTATION_0:                                                                         
5378         case Surface.ROTATION_180:                                                                       
5379             // We are currently in the same basic orientation as the natural orientation                 
5380             naturalOri = configOri;                                                                      
5381             break;                                                                                       
5382         case Surface.ROTATION_90:                                                                        
5383         case Surface.ROTATION_270:                                                                       
5384             // We are currently in the other basic orientation to the natural orientation                
5385             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
5386                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
5387             break;                                                                                       
5388         }                                                                                                
5389                                                                                                          
5390         int[] oriMap = {                                                                                 
5391                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
5392                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
5393                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
5394                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
5395         };                                                                                               
5396         // Since the map starts at portrait, we need to offset if this device's natural orientation      
5397         // is landscape.                                                                                 
5398         int indexOffset = 0;                                                                             
5399         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
5400             indexOffset = 1;                                                                             
5401         }                                                                                                
5402         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
5403     }                                                                                                    
5404                                                                                                          
5405     public boolean isRotationEnabled() {                                                                 
5406         boolean enableRotation = sForceEnableRotation ||                                                 
5407                 getResources().getBoolean(R.bool.allow_rotation);                                        
5408         return enableRotation;                                                                           
5409     }                                                                                                    
5410     public void lockScreenOrientation() {                                                                
5411         if (isRotationEnabled()) {                                                                       
5412             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                    
5413                     .getConfiguration().orientation));                                                   
5414         }                                                                                                
5415     }                                                                                                    
5416     public void unlockScreenOrientation(boolean immediate) {                                             
5417         if (isRotationEnabled()) {                                                                       
5418             if (immediate) {                                                                             
5419                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
5420             } else {                                                                                     
5421                 mHandler.postDelayed(new Runnable() {                                                    
5422                     public void run() {                                                                  
5423                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
5424                     }                                                                                    
5425                 }, mRestoreScreenOrientationDelay);                                                      
5426             }                                                                                            
5427         }                                                                                                
5428     }                                                                                                    
5429                                                                                                          
5430     /**                                                                                                  
5431      * Called when the SearchBar hint should be changed.                                                 
5432      *                                                                                                   
5433      * @param hint the hint to be displayed in the search bar.                                           
5434      */                                                                                                  
5435     protected void onSearchBarHintChanged(String hint) {                                                 
5436                                                                                                          
5437     }                                                                                                    
5438                                                                                                          
5439     protected boolean isLauncherPreinstalled() {                                                         
5440         PackageManager pm = getPackageManager();                                                         
5441         try {                                                                                            
5442             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
5443             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
5444                 return true;                                                                             
5445             } else {                                                                                     
5446                 return false;                                                                            
5447             }                                                                                            
5448         } catch (NameNotFoundException e) {                                                              
5449             e.printStackTrace();                                                                         
5450             return false;                                                                                
5451         }                                                                                                
5452     }                                                                                                    
5453                                                                                                          
5454     /**                                                                                                  
5455      * This method indicates whether or not we should suggest default wallpaper dimensions               
5456      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
5457      */                                                                                                  
5458     protected boolean overrideWallpaperDimensions() {                                                    
5459         return true;                                                                                     
5460     }                                                                                                    
5461                                                                                                          
5462     protected boolean shouldClingFocusHotseatApp() {                                                     
5463         return false;                                                                                    
5464     }                                                                                                    
5465     protected String getFirstRunClingSearchBarHint() {                                                   
5466         return "";                                                                                       
5467     }                                                                                                    
5468     protected String getFirstRunCustomContentHint() {                                                    
5469         return "";                                                                                       
5470     }                                                                                                    
5471     protected int getFirstRunFocusedHotseatAppDrawableId() {                                             
5472         return -1;                                                                                       
5473     }                                                                                                    
5474     protected ComponentName getFirstRunFocusedHotseatAppComponentName() {                                
5475         return null;                                                                                     
5476     }                                                                                                    
5477     protected int getFirstRunFocusedHotseatAppRank() {                                                   
5478         return -1;                                                                                       
5479     }                                                                                                    
5480     protected String getFirstRunFocusedHotseatAppBubbleTitle() {                                         
5481         return "";                                                                                       
5482     }                                                                                                    
5483     protected String getFirstRunFocusedHotseatAppBubbleDescription() {                                   
5484         return "";                                                                                       
5485     }                                                                                                    
5486                                                                                                          
5487     /**                                                                                                  
5488      * To be overridden by subclasses to indicate that there is an activity to launch                    
5489      * before showing the standard launcher experience.                                                  
5490      */                                                                                                  
5491     protected boolean hasFirstRunActivity() {                                                            
5492         return false;                                                                                    
5493     }                                                                                                    
5494                                                                                                          
5495     /**                                                                                                  
5496      * To be overridden by subclasses to launch any first run activity                                   
5497      */                                                                                                  
5498     protected Intent getFirstRunActivity() {                                                             
5499         return null;                                                                                     
5500     }                                                                                                    
5501                                                                                                          
5502     private boolean shouldRunFirstRunActivity() {                                                        
5503         return !ActivityManager.isRunningInTestHarness() &&                                              
5504                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
5505     }                                                                                                    
5506                                                                                                          
5507     protected boolean hasRunFirstRunActivity() {                                                         
5508         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
5509     }                                                                                                    
5510                                                                                                          
5511     public boolean showFirstRunActivity() {                                                              
5512         if (shouldRunFirstRunActivity() &&                                                               
5513                 hasFirstRunActivity()) {                                                                 
5514             Intent firstRunIntent = getFirstRunActivity();                                               
5515             if (firstRunIntent != null) {                                                                
5516                 startActivity(firstRunIntent);                                                           
5517                 markFirstRunActivityShown();                                                             
5518                 return true;                                                                             
5519             }                                                                                            
5520         }                                                                                                
5521         return false;                                                                                    
5522     }                                                                                                    
5523                                                                                                          
5524     private void markFirstRunActivityShown() {                                                           
5525         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5526         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
5527         editor.apply();                                                                                  
5528     }                                                                                                    
5529                                                                                                          
5530     /**                                                                                                  
5531      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
5532      * screen that must be displayed and dismissed.                                                      
5533      */                                                                                                  
5534     protected boolean hasDismissableIntroScreen() {                                                      
5535         return false;                                                                                    
5536     }                                                                                                    
5537                                                                                                          
5538     /**                                                                                                  
5539      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
5540      */                                                                                                  
5541     protected View getIntroScreen() {                                                                    
5542         return null;                                                                                     
5543     }                                                                                                    
5544                                                                                                          
5545     /**                                                                                                  
5546      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
5547      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
5548      */                                                                                                  
5549     private boolean shouldShowIntroScreen() {                                                            
5550         return hasDismissableIntroScreen() &&                                                            
5551                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
5552     }                                                                                                    
5553                                                                                                          
5554     protected void showIntroScreen() {                                                                   
5555         View introScreen = getIntroScreen();                                                             
5556         changeWallpaperVisiblity(false);                                                                 
5557         if (introScreen != null) {                                                                       
5558             mDragLayer.showOverlayView(introScreen);                                                     
5559         }                                                                                                
5560     }                                                                                                    
5561                                                                                                          
5562     public void dismissIntroScreen() {                                                                   
5563         markIntroScreenDismissed();                                                                      
5564         if (showFirstRunActivity()) {                                                                    
5565             // We delay hiding the intro view until the first run activity is showing. This              
5566             // avoids a blip.                                                                            
5567             mWorkspace.postDelayed(new Runnable() {                                                      
5568                 @Override                                                                                
5569                 public void run() {                                                                      
5570                     mDragLayer.dismissOverlayView();                                                     
5571                     showFirstRunClings();                                                                
5572                 }                                                                                        
5573             }, ACTIVITY_START_DELAY);                                                                    
5574         } else {                                                                                         
5575             mDragLayer.dismissOverlayView();                                                             
5576             showFirstRunClings();                                                                        
5577         }                                                                                                
5578         changeWallpaperVisiblity(true);                                                                  
5579     }                                                                                                    
5580                                                                                                          
5581     private void markIntroScreenDismissed() {                                                            
5582         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5583         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
5584         editor.apply();                                                                                  
5585     }                                                                                                    
5586                                                                                                          
5587     private void showFirstRunClings() {                                                                  
5588         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
5589         // on the device, then we always show the first run cling experience (or if there is no          
5590         // launcher2). Otherwise, we prompt the user upon started for migration                          
5591         LauncherClings launcherClings = new LauncherClings(this);                                        
5592         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
5593             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
5594                 launcherClings.showMigrationCling();                                                     
5595             } else {                                                                                     
5596                 launcherClings.showLongPressCling(true);                                                 
5597             }                                                                                            
5598         }                                                                                                
5599     }                                                                                                    
5600                                                                                                          
5601     void showWorkspaceSearchAndHotseat() {                                                               
5602         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
5603         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
5604         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
5605         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
5606     }                                                                                                    
5607                                                                                                          
5608     void hideWorkspaceSearchAndHotseat() {                                                               
5609         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
5610         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
5611         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
5612         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
5613     }                                                                                                    
5614                                                                                                          
5615     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
5616         // Called from search suggestion, not supported in other profiles.                               
5617         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
5618         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
5619         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
5620                 myUser);                                                                                 
5621         if (activityInfo == null) {                                                                      
5622             return null;                                                                                 
5623         }                                                                                                
5624         return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                
5625     }                                                                                                    
5626                                                                                                          
5627     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5628             Bitmap icon) {                                                                               
5629         // Called from search suggestion, not supported in other profiles.                               
5630         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
5631                 UserHandleCompat.myUserHandle());                                                        
5632     }                                                                                                    
5633                                                                                                          
5634     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5635             Bitmap icon, UserHandleCompat user) {                                                        
5636         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
5637         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
5638         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
5639     }                                                                                                    
5640                                                                                                          
5641     protected void moveWorkspaceToDefaultScreen() {                                                      
5642         mWorkspace.moveToDefaultScreen(false);                                                           
5643     }                                                                                                    
5644                                                                                                          
5645     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
5646         dragView.setTag(dragInfo);                                                                       
5647         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
5648         mWorkspace.beginExternalDragShared(dragView, source);                                            
5649     }                                                                                                    
5650                                                                                                          
5651     @Override                                                                                            
5652     public void onPageSwitch(View newPage, int newPageIndex) {                                           
5653     }                                                                                                    
5654                                                                                                          
5655     /**                                                                                                  
5656      * Prints out out state for debugging.                                                               
5657      */                                                                                                  
5658     public void dumpState() {                                                                            
5659         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
5660         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
5661         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
5662         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
5663         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
5664         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
5665         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
5666         mModel.dumpState();                                                                              
5667                                                                                                          
5668         if (mAppsCustomizeContent != null) {                                                             
5669             mAppsCustomizeContent.dumpState();                                                           
5670         }                                                                                                
5671         Log.d(TAG, "END launcher3 dump state");                                                          
5672     }                                                                                                    
5673                                                                                                          
5674     @Override                                                                                            
5675     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
5676         super.dump(prefix, fd, writer, args);                                                            
5677         synchronized (sDumpLogs) {                                                                       
5678             writer.println(" ");                                                                         
5679             writer.println("Debug logs: ");                                                              
5680             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
5681                 writer.println("  " + sDumpLogs.get(i));                                                 
5682             }                                                                                            
5683         }                                                                                                
5684     }                                                                                                    
5685                                                                                                          
5686     public static void dumpDebugLogsToConsole() {                                                        
5687         if (DEBUG_DUMP_LOG) {                                                                            
5688             synchronized (sDumpLogs) {                                                                   
5689                 Log.d(TAG, "");                                                                          
5690                 Log.d(TAG, "*********************");                                                     
5691                 Log.d(TAG, "Launcher debug logs: ");                                                     
5692                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
5693                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
5694                 }                                                                                        
5695                 Log.d(TAG, "*********************");                                                     
5696                 Log.d(TAG, "");                                                                          
5697             }                                                                                            
5698         }                                                                                                
5699     }                                                                                                    
5700                                                                                                          
5701     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
5702         addDumpLog(tag, log, null, debugLog);                                                            
5703     }                                                                                                    
5704                                                                                                          
5705     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
5706         if (debugLog) {                                                                                  
5707             if (e != null) {                                                                             
5708                 Log.d(tag, log, e);                                                                      
5709             } else {                                                                                     
5710                 Log.d(tag, log);                                                                         
5711             }                                                                                            
5712         }                                                                                                
5713         if (DEBUG_DUMP_LOG) {                                                                            
5714             sDateStamp.setTime(System.currentTimeMillis());                                              
5715             synchronized (sDumpLogs) {                                                                   
5716                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
5717                     + (e == null ? "" : (", Exception: " + e)));                                         
5718             }                                                                                            
5719         }                                                                                                
5720     }                                                                                                    
5721                                                                                                          
5722     public void dumpLogsToLocalData() {                                                                  
5723         if (DEBUG_DUMP_LOG) {                                                                            
5724             new AsyncTask<Void, Void, Void>() {                                                          
5725                 public Void doInBackground(Void ... args) {                                              
5726                     boolean success = false;                                                             
5727                     sDateStamp.setTime(sRunStart);                                                       
5728                     String FILENAME = sDateStamp.getMonth() + "-"                                        
5729                             + sDateStamp.getDay() + "_"                                                  
5730                             + sDateStamp.getHours() + "-"                                                
5731                             + sDateStamp.getMinutes() + "_"                                              
5732                             + sDateStamp.getSeconds() + ".txt";                                          
5733                                                                                                          
5734                     FileOutputStream fos = null;                                                         
5735                     File outFile = null;                                                                 
5736                     try {                                                                                
5737                         outFile = new File(getFilesDir(), FILENAME);                                     
5738                         outFile.createNewFile();                                                         
5739                         fos = new FileOutputStream(outFile);                                             
5740                     } catch (Exception e) {                                                              
5741                         e.printStackTrace();                                                             
5742                     }                                                                                    
5743                     if (fos != null) {                                                                   
5744                         PrintWriter writer = new PrintWriter(fos);                                       
5745                                                                                                          
5746                         writer.println(" ");                                                             
5747                         writer.println("Debug logs: ");                                                  
5748                         synchronized (sDumpLogs) {                                                       
5749                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
5750                                 writer.println("  " + sDumpLogs.get(i));                                 
5751                             }                                                                            
5752                         }                                                                                
5753                         writer.close();                                                                  
5754                     }                                                                                    
5755                     try {                                                                                
5756                         if (fos != null) {                                                               
5757                             fos.close();                                                                 
5758                             success = true;                                                              
5759                         }                                                                                
5760                     } catch (IOException e) {                                                            
5761                         e.printStackTrace();                                                             
5762                     }                                                                                    
5763                     return null;                                                                         
5764                 }                                                                                        
5765             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
5766         }                                                                                                
5767     }                                                                                                    
5768 }                                                                                                        
5769                                                                                                          
5770 interface LauncherTransitionable {                                                                       
5771     View getContent();                                                                                   
5772     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
5773     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
5774     void onLauncherTransitionStep(Launcher l, float t);                                                  
5775     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
5776 }                                                                                                        
5777                                                                                                          
5778 interface DebugIntents {                                                                                 
5779     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
5780     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
5781 }                                                                                                        
   1                                                                                                          
   2 /*                                                                                                       
   3  * Copyright (C) 2008 The Android Open Source Project                                                    
   4  *                                                                                                       
   5  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   6  * you may not use this file except in compliance with the License.                                      
   7  * You may obtain a copy of the License at                                                               
   8  *                                                                                                       
   9  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
  10  *                                                                                                       
  11  * Unless required by applicable law or agreed to in writing, software                                   
  12  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  14  * See the License for the specific language governing permissions and                                   
  15  * limitations under the License.                                                                        
  16  */                                                                                                      
  17                                                                                                          
  18 package com.android.launcher3;                                                                           
  19                                                                                                          
  20 import android.animation.Animator;                                                                       
  21 import android.animation.AnimatorListenerAdapter;                                                        
  22 import android.animation.AnimatorSet;                                                                    
  23 import android.animation.ObjectAnimator;                                                                 
  24 import android.animation.PropertyValuesHolder;                                                           
  25 import android.animation.TimeInterpolator;                                                               
  26 import android.animation.ValueAnimator;                                                                  
  27 import android.annotation.TargetApi;                                                                     
  28 import android.app.Activity;                                                                             
  29 import android.app.ActivityManager;                                                                      
  30 import android.app.ActivityOptions;                                                                      
  31 import android.app.AlertDialog;                                                                          
  32 import android.app.SearchManager;                                                                        
  33 import android.appwidget.AppWidgetHostView;                                                              
  34 import android.appwidget.AppWidgetManager;                                                               
  35 import android.appwidget.AppWidgetProviderInfo;                                                          
  36 import android.content.ActivityNotFoundException;                                                        
  37 import android.content.BroadcastReceiver;                                                                
  38 import android.content.ComponentCallbacks2;                                                              
  39 import android.content.ComponentName;                                                                    
  40 import android.content.ContentResolver;                                                                  
  41 import android.content.Context;                                                                          
  42 import android.content.DialogInterface;                                                                  
  43 import android.content.Intent;                                                                           
  44 import android.content.IntentFilter;                                                                     
  45 import android.content.SharedPreferences;                                                                
  46 import android.content.pm.ActivityInfo;                                                                  
  47 import android.content.pm.ApplicationInfo;                                                               
  48 import android.content.pm.PackageManager;                                                                
  49 import android.content.pm.PackageManager.NameNotFoundException;                                          
  50 import android.content.res.Configuration;                                                                
  51 import android.content.res.Resources;                                                                    
  52 import android.database.ContentObserver;                                                                 
  53 import android.graphics.Bitmap;                                                                          
  54 import android.graphics.Canvas;                                                                          
  55 import android.graphics.Color;                                                                           
  56 import android.graphics.Point;                                                                           
  57 import android.graphics.PorterDuff;                                                                      
  58 import android.graphics.Rect;                                                                            
  59 import android.graphics.drawable.Drawable;                                                               
  60 import android.net.Uri;                                                                                  
  61 import android.os.AsyncTask;                                                                             
  62 import android.os.Build;                                                                                 
  63 import android.os.Bundle;                                                                                
  64 import android.os.Environment;                                                                           
  65 import android.os.Handler;                                                                               
  66 import android.os.Message;                                                                               
  67 import android.os.StrictMode;                                                                            
  68 import android.os.SystemClock;                                                                           
  69 import android.speech.RecognizerIntent;                                                                  
  70 import android.text.Selection;                                                                           
  71 import android.text.SpannableStringBuilder;                                                              
  72 import android.text.TextUtils;                                                                           
  73 import android.text.method.TextKeyListener;                                                              
  74 import android.util.DisplayMetrics;                                                                      
  75 import android.util.Log;                                                                                 
  76 import android.view.ContextThemeWrapper;                                                                 
  77 import android.view.Display;                                                                             
  78 import android.view.Gravity;                                                                             
  79 import android.view.HapticFeedbackConstants;                                                             
  80 import android.view.KeyEvent;                                                                            
  81 import android.view.LayoutInflater;                                                                      
  82 import android.view.Menu;                                                                                
  83 import android.view.MotionEvent;                                                                         
  84 import android.view.Surface;                                                                             
  85 import android.view.View;                                                                                
  86 import android.view.View.OnClickListener;                                                                
  87 import android.view.View.OnLongClickListener;                                                            
  88 import android.view.ViewAnimationUtils;                                                                  
  89 import android.view.ViewGroup;                                                                           
  90 import android.view.ViewTreeObserver;                                                                    
  91 import android.view.ViewTreeObserver.OnGlobalLayoutListener;                                             
  92 import android.view.Window;                                                                              
  93 import android.view.WindowManager;                                                                       
  94 import android.view.accessibility.AccessibilityEvent;                                                    
  95 import android.view.animation.AccelerateInterpolator;                                                    
  96 import android.view.animation.DecelerateInterpolator;                                                    
  97 import android.view.animation.Interpolator;                                                              
  98 import android.view.inputmethod.InputMethodManager;                                                      
  99 import android.widget.Advanceable;                                                                       
 100 import android.widget.FrameLayout;                                                                       
 101 import android.widget.ImageView;                                                                         
 102 import android.widget.TextView;                                                                          
 103 import android.widget.Toast;                                                                             
 104                                                                                                          
 105 import com.android.launcher3.DropTarget.DragObject;                                                      
 106 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 107 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 108 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 109 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 110 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 111 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 112 import com.android.launcher3.compat.UserHandleCompat;                                                    
 113 import com.android.launcher3.compat.UserManagerCompat;                                                   
 114                                                                                                          
 115 import java.io.DataInputStream;                                                                          
 116 import java.io.DataOutputStream;                                                                         
 117 import java.io.File;                                                                                     
 118 import java.io.FileDescriptor;                                                                           
 119 import java.io.FileNotFoundException;                                                                    
 120 import java.io.FileOutputStream;                                                                         
 121 import java.io.IOException;                                                                              
 122 import java.io.PrintWriter;                                                                              
 123 import java.lang.reflect.Field;                                                                          
 124 import java.lang.reflect.InvocationTargetException;                                                      
 125 import java.lang.reflect.Method;                                                                         
 126 import java.text.DateFormat;                                                                             
 127 import java.util.ArrayList;                                                                              
 128 import java.util.Collection;                                                                             
 129 import java.util.Date;                                                                                   
 130 import java.util.HashMap;                                                                                
 131 import java.util.List;                                                                                   
 132 import java.util.concurrent.atomic.AtomicInteger;                                                        
 133                                                                                                          
 134 /**                                                                                                      
 135  * Default launcher application.                                                                         
 136  */                                                                                                      
 137 public class Launcher extends Activity                                                                   
 138         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 139                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {            
 140     static final String TAG = "Launcher";                                                                
 141     static final boolean LOGD = false;                                                                   
 142                                                                                                          
 143     static final boolean PROFILE_STARTUP = false;                                                        
 144     static final boolean DEBUG_WIDGETS = false;                                                          
 145     static final boolean DEBUG_STRICT_MODE = false;                                                      
 146     static final boolean DEBUG_RESUME_TIME = false;                                                      
 147     static final boolean DEBUG_DUMP_LOG = false;                                                         
 148                                                                                                          
 149     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 150                                                                                                          
 151     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 152     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 153     private static final int REQUEST_PICK_SHORTCUT = 7;                                                  
 154     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 155     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 156                                                                                                          
 157     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 158     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 159                                                                                                          
 160     /**                                                                                                  
 161      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 162      * request codes used internally.                                                                    
 163      */                                                                                                  
 164     protected static final int REQUEST_LAST = 100;                                                       
 165                                                                                                          
 166     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 167                                                                                                          
 168     static final int SCREEN_COUNT = 5;                                                                   
 169     static final int DEFAULT_SCREEN = 2;                                                                 
 170                                                                                                          
 171     private static final String PREFERENCES = "launcher.preferences";                                    
 172     // To turn on these properties, type                                                                 
 173     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 174     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                        
 175     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 176     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                
 177                                                                                                          
 178     // The Intent extra that defines whether to ignore the launch animation                              
 179     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 180             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 181                                                                                                          
 182     // Type: int                                                                                         
 183     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 184     // Type: int                                                                                         
 185     private static final String RUNTIME_STATE = "launcher.state";                                        
 186     // Type: int                                                                                         
 187     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 190     // Type: int                                                                                         
 191     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 192     // Type: int                                                                                         
 193     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 194     // Type: boolean                                                                                     
 195     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 196     // Type: long                                                                                        
 197     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 198     // Type: int                                                                                         
 199     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 200     // Type: int                                                                                         
 201     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 202     // Type: parcelable                                                                                  
 203     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 204     // Type: parcelable                                                                                  
 205     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 206     // Type: int[]                                                                                       
 207     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 208                                                                                                          
 209     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 210     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 211                                                                                                          
 212     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 213     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 214             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 215                                                                                                          
 216     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";        
 217     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                      
 218             "com.android.launcher.toolbar_search_icon";                                                  
 219     private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                
 220             "com.android.launcher.toolbar_voice_search_icon";                                            
 221                                                                                                          
 222     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 223     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 224                                                                                                          
 225     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 226                                                                                                          
 227     /** The different states that Launcher can be in. */                                                 
 228     private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                
 229     private State mState = State.WORKSPACE;                                                              
 230     private AnimatorSet mStateAnimation;                                                                 
 231                                                                                                          
 232     private boolean mIsSafeModeEnabled;                                                                  
 233                                                                                                          
 234     static final int APPWIDGET_HOST_ID = 1024;                                                           
 235     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 236     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 237     private static final int ACTIVITY_START_DELAY = 1000;                                                
 238                                                                                                          
 239     private static final Object sLock = new Object();                                                    
 240     private static int sScreen = DEFAULT_SCREEN;                                                         
 241                                                                                                          
 242     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 243     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 244                                                                                                          
 245     // How long to wait before the new-shortcut animation automatically pans the workspace               
 246     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 247     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 248     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 249     private static final int SINGLE_FRAME_DELAY = 16;                                                    
 250                                                                                                          
 251     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 252             = new CloseSystemDialogsIntentReceiver();                                                    
 253     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 254                                                                                                          
 255     private LayoutInflater mInflater;                                                                    
 256                                                                                                          
 257     private Workspace mWorkspace;                                                                        
 258     private View mLauncherView;                                                                          
 259     private View mPageIndicators;                                                                        
 260     private DragLayer mDragLayer;                                                                        
 261     private DragController mDragController;                                                              
 262     private View mWeightWatcher;                                                                         
 263                                                                                                          
 264     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 265     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 266                                                                                                          
 267     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 268     private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                 
 269     private int mPendingAddWidgetId = -1;                                                                
 270                                                                                                          
 271     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 272                                                                                                          
 273     private FolderInfo mFolderInfo;                                                                      
 274                                                                                                          
 275     private Hotseat mHotseat;                                                                            
 276     private ViewGroup mOverviewPanel;                                                                    
 277                                                                                                          
 278     private View mAllAppsButton;                                                                         
 279                                                                                                          
 280     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 281     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 282     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 283     private boolean mAutoAdvanceRunning = false;                                                         
 284     private View mQsb;                                                                                   
 285                                                                                                          
 286     private Bundle mSavedState;                                                                          
 287     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 288     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 289     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 290     private State mOnResumeState = State.NONE;                                                           
 291                                                                                                          
 292     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 293                                                                                                          
 294     private boolean mWorkspaceLoading = true;                                                            
 295                                                                                                          
 296     private boolean mPaused = true;                                                                      
 297     private boolean mRestoring;                                                                          
 298     private boolean mWaitingForResult;                                                                   
 299     private boolean mOnResumeNeedsLoad;                                                                  
 300                                                                                                          
 301     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 302     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 303                                                                                                          
 304     private Bundle mSavedInstanceState;                                                                  
 305                                                                                                          
 306     private LauncherModel mModel;                                                                        
 307     private IconCache mIconCache;                                                                        
 308     private boolean mUserPresent = true;                                                                 
 309     private boolean mVisible = false;                                                                    
 310     private boolean mHasFocus = false;                                                                   
 311     private boolean mAttached = false;                                                                   
 312                                                                                                          
 313     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 314                                                                                                          
 315     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 316                                                                                                          
 317     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 318                                                                                                          
 319     // Related to the auto-advancing of widgets                                                          
 320     private final int ADVANCE_MSG = 1;                                                                   
 321     private final int mAdvanceInterval = 20000;                                                          
 322     private final int mAdvanceStagger = 250;                                                             
 323     private long mAutoAdvanceSentTime;                                                                   
 324     private long mAutoAdvanceTimeLeft = -1;                                                              
 325     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                     
 326         new HashMap<View, AppWidgetProviderInfo>();                                                      
 327                                                                                                          
 328     // Determines how long to wait after a rotation before restoring the screen orientation to           
 329     // match the sensor state.                                                                           
 330     private final int mRestoreScreenOrientationDelay = 500;                                              
 331                                                                                                          
 332     // External icons saved in case of resource changes, orientation, etc.                               
 333     private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];           
 334     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];            
 335                                                                                                          
 336     private Drawable mWorkspaceBackgroundDrawable;                                                       
 337                                                                                                          
 338     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 339     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 340                                                                                                          
 341     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 342     static Date sDateStamp = new Date();                                                                 
 343     static DateFormat sDateFormat =                                                                      
 344             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 345     static long sRunStart = System.currentTimeMillis();                                                  
 346     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 347                                                                                                          
 348     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 349     // it from the context.                                                                              
 350     private SharedPreferences mSharedPrefs;                                                              
 351                                                                                                          
 352     private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                   
 353                                                                                                          
 354     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 355     // when we scroll to that page on resume.                                                            
 356     private ImageView mFolderIconImageView;                                                              
 357     private Bitmap mFolderIconBitmap;                                                                    
 358     private Canvas mFolderIconCanvas;                                                                    
 359     private Rect mRectForFolderAnimation = new Rect();                                                   
 360                                                                                                          
 361     private BubbleTextView mWaitingForResume;                                                            
 362                                                                                                          
 363     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 364         public void run() {                                                                              
 365             if (mWorkspace != null) {                                                                    
 366                 mWorkspace.buildPageHardwareLayers();                                                    
 367             }                                                                                            
 368         }                                                                                                
 369     };                                                                                                   
 370                                                                                                          
 371     private static PendingAddArguments sPendingAddItem;                                                  
 372                                                                                                          
 373     public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);      
 374                                                                                                          
 375     private static class PendingAddArguments {                                                           
 376         int requestCode;                                                                                 
 377         Intent intent;                                                                                   
 378         long container;                                                                                  
 379         long screenId;                                                                                   
 380         int cellX;                                                                                       
 381         int cellY;                                                                                       
 382         int appWidgetId;                                                                                 
 383     }                                                                                                    
 384                                                                                                          
 385     private Stats mStats;                                                                                
 386                                                                                                          
 387     FocusIndicatorView mFocusHandler;                                                                    
 388                                                                                                          
 389     static boolean isPropertyEnabled(String propertyName) {                                              
 390         return Log.isLoggable(propertyName, Log.VERBOSE);                                                
 391     }                                                                                                    
 392                                                                                                          
 393     @Override                                                                                            
 394     protected void onCreate(Bundle savedInstanceState) {                                                 
 395         if (DEBUG_STRICT_MODE) {                                                                         
 396             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 397                     .detectDiskReads()                                                                   
 398                     .detectDiskWrites()                                                                  
 399                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 400                     .penaltyLog()                                                                        
 401                     .build());                                                                           
 402             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 403                     .detectLeakedSqlLiteObjects()                                                        
 404                     .detectLeakedClosableObjects()                                                       
 405                     .penaltyLog()                                                                        
 406                     .penaltyDeath()                                                                      
 407                     .build());                                                                           
 408         }                                                                                                
 409                                                                                                          
 410         super.onCreate(savedInstanceState);                                                              
 411                                                                                                          
 412         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 413         LauncherAppState app = LauncherAppState.getInstance();                                           
 414         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 415         // Determine the dynamic grid properties                                                         
 416         Point smallestSize = new Point();                                                                
 417         Point largestSize = new Point();                                                                 
 418         Point realSize = new Point();                                                                    
 419         Display display = getWindowManager().getDefaultDisplay();                                        
 420         display.getCurrentSizeRange(smallestSize, largestSize);                                          
 421         display.getRealSize(realSize);                                                                   
 422         DisplayMetrics dm = new DisplayMetrics();                                                        
 423         display.getMetrics(dm);                                                                          
 424                                                                                                          
 425         // Lazy-initialize the dynamic grid                                                              
 426         DeviceProfile grid = app.initDynamicGrid(this,                                                   
 427                 Math.min(smallestSize.x, smallestSize.y),                                                
 428                 Math.min(largestSize.x, largestSize.y),                                                  
 429                 realSize.x, realSize.y,                                                                  
 430                 dm.widthPixels, dm.heightPixels);                                                        
 431                                                                                                          
 432         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 433         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 434                 Context.MODE_PRIVATE);                                                                   
 435         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 436         mModel = app.setLauncher(this);                                                                  
 437         mIconCache = app.getIconCache();                                                                 
 438         mIconCache.flushInvalidIcons(grid);                                                              
 439         mDragController = new DragController(this);                                                      
 440         mInflater = getLayoutInflater();                                                                 
 441                                                                                                          
 442         mStats = new Stats(this);                                                                        
 443                                                                                                          
 444         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 445                                                                                                          
 446         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 447         mAppWidgetHost.startListening();                                                                 
 448                                                                                                          
 449         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 450         // this also ensures that any synchronous binding below doesn't re-trigger another               
 451         // LauncherModel load.                                                                           
 452         mPaused = false;                                                                                 
 453                                                                                                          
 454         if (PROFILE_STARTUP) {                                                                           
 455             android.os.Debug.startMethodTracing(                                                         
 456                     Environment.getExternalStorageDirectory() + "/launcher");                            
 457         }                                                                                                
 458                                                                                                          
 459         checkForLocaleChange();                                                                          
 460         setContentView(R.layout.launcher);                                                               
 461                                                                                                          
 462         setupViews();                                                                                    
 463         grid.layout(this);                                                                               
 464                                                                                                          
 465         registerContentObservers();                                                                      
 466                                                                                                          
 467         lockAllApps();                                                                                   
 468                                                                                                          
 469         mSavedState = savedInstanceState;                                                                
 470         restoreState(mSavedState);                                                                       
 471                                                                                                          
 472         if (PROFILE_STARTUP) {                                                                           
 473             android.os.Debug.stopMethodTracing();                                                        
 474         }                                                                                                
 475                                                                                                          
 476         if (!mRestoring) {                                                                               
 477             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 478                 // If the user leaves launcher, then we should just load items asynchronously when       
 479                 // they return.                                                                          
 480                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 481             } else {                                                                                     
 482                 // We only load the page synchronously if the user rotates (or triggers a                
 483                 // configuration change) while launcher is in the foreground                             
 484                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 485             }                                                                                            
 486         }                                                                                                
 487                                                                                                          
 488         // For handling default keys                                                                     
 489         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 490         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 491                                                                                                          
 492         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 493         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 494                                                                                                          
 495         updateGlobalIcons();                                                                             
 496                                                                                                          
 497         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 498         unlockScreenOrientation(true);                                                                   
 499                                                                                                          
 500         if (shouldShowIntroScreen()) {                                                                   
 501             showIntroScreen();                                                                           
 502         } else {                                                                                         
 503             showFirstRunActivity();                                                                      
 504             showFirstRunClings();                                                                        
 505         }                                                                                                
 506     }                                                                                                    
 507                                                                                                          
 508     @Override                                                                                            
 509     public void onLauncherProviderChange() { }                                                           
 510                                                                                                          
 511     /** To be overriden by subclasses to hint to Launcher that we have custom content */                 
 512     protected boolean hasCustomContentToLeft() {                                                         
 513         return false;                                                                                    
 514     }                                                                                                    
 515                                                                                                          
 516     /**                                                                                                  
 517      * To be overridden by subclasses to populate the custom content container and call                  
 518      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 519      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 520      */                                                                                                  
 521     protected void populateCustomContentContainer() {                                                    
 522     }                                                                                                    
 523                                                                                                          
 524     /**                                                                                                  
 525      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 526      * ensure the custom content page is added or removed if necessary.                                  
 527      */                                                                                                  
 528     protected void invalidateHasCustomContentToLeft() {                                                  
 529         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 530             // Not bound yet, wait for bindScreens to be called.                                         
 531             return;                                                                                      
 532         }                                                                                                
 533                                                                                                          
 534         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 535             // Create the custom content page and call the subclass to populate it.                      
 536             mWorkspace.createCustomContentContainer();                                                   
 537             populateCustomContentContainer();                                                            
 538         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 539             mWorkspace.removeCustomContentPage();                                                        
 540         }                                                                                                
 541     }                                                                                                    
 542                                                                                                          
 543     private void updateGlobalIcons() {                                                                   
 544         boolean searchVisible = false;                                                                   
 545         boolean voiceVisible = false;                                                                    
 546         // If we have a saved version of these external icons, we load them up immediately               
 547         int coi = getCurrentOrientationIndexForGlobalIcons();                                            
 548         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                           
 549             searchVisible = updateGlobalSearchIcon();                                                    
 550             voiceVisible = updateVoiceSearchIcon(searchVisible);                                         
 551         }                                                                                                
 552         if (sGlobalSearchIcon[coi] != null) {                                                            
 553              updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                             
 554              searchVisible = true;                                                                       
 555         }                                                                                                
 556         if (sVoiceSearchIcon[coi] != null) {                                                             
 557             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                
 558             voiceVisible = true;                                                                         
 559         }                                                                                                
 560         if (mSearchDropTargetBar != null) {                                                              
 561             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
 562         }                                                                                                
 563     }                                                                                                    
 564                                                                                                          
 565     private void checkForLocaleChange() {                                                                
 566         if (sLocaleConfiguration == null) {                                                              
 567             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 568                 @Override                                                                                
 569                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 570                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 571                     readConfiguration(Launcher.this, localeConfiguration);                               
 572                     return localeConfiguration;                                                          
 573                 }                                                                                        
 574                                                                                                          
 575                 @Override                                                                                
 576                 protected void onPostExecute(LocaleConfiguration result) {                               
 577                     sLocaleConfiguration = result;                                                       
 578                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 579                 }                                                                                        
 580             }.execute();                                                                                 
 581             return;                                                                                      
 582         }                                                                                                
 583                                                                                                          
 584         final Configuration configuration = getResources().getConfiguration();                           
 585                                                                                                          
 586         final String previousLocale = sLocaleConfiguration.locale;                                       
 587         final String locale = configuration.locale.toString();                                           
 588                                                                                                          
 589         final int previousMcc = sLocaleConfiguration.mcc;                                                
 590         final int mcc = configuration.mcc;                                                               
 591                                                                                                          
 592         final int previousMnc = sLocaleConfiguration.mnc;                                                
 593         final int mnc = configuration.mnc;                                                               
 594                                                                                                          
 595         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 596                                                                                                          
 597         if (localeChanged) {                                                                             
 598             sLocaleConfiguration.locale = locale;                                                        
 599             sLocaleConfiguration.mcc = mcc;                                                              
 600             sLocaleConfiguration.mnc = mnc;                                                              
 601                                                                                                          
 602             mIconCache.flush();                                                                          
 603                                                                                                          
 604             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 605             new AsyncTask<Void, Void, Void>() {                                                          
 606                 public Void doInBackground(Void ... args) {                                              
 607                     writeConfiguration(Launcher.this, localeConfiguration);                              
 608                     return null;                                                                         
 609                 }                                                                                        
 610             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 611         }                                                                                                
 612     }                                                                                                    
 613                                                                                                          
 614     private static class LocaleConfiguration {                                                           
 615         public String locale;                                                                            
 616         public int mcc = -1;                                                                             
 617         public int mnc = -1;                                                                             
 618     }                                                                                                    
 619                                                                                                          
 620     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 621         DataInputStream in = null;                                                                       
 622         try {                                                                                            
 623             in = new DataInputStream(context.openFileInput(PREFERENCES));                                
 624             configuration.locale = in.readUTF();                                                         
 625             configuration.mcc = in.readInt();                                                            
 626             configuration.mnc = in.readInt();                                                            
 627         } catch (FileNotFoundException e) {                                                              
 628             // Ignore                                                                                    
 629         } catch (IOException e) {                                                                        
 630             // Ignore                                                                                    
 631         } finally {                                                                                      
 632             if (in != null) {                                                                            
 633                 try {                                                                                    
 634                     in.close();                                                                          
 635                 } catch (IOException e) {                                                                
 636                     // Ignore                                                                            
 637                 }                                                                                        
 638             }                                                                                            
 639         }                                                                                                
 640     }                                                                                                    
 641                                                                                                          
 642     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 643         DataOutputStream out = null;                                                                     
 644         try {                                                                                            
 645             out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));               
 646             out.writeUTF(configuration.locale);                                                          
 647             out.writeInt(configuration.mcc);                                                             
 648             out.writeInt(configuration.mnc);                                                             
 649             out.flush();                                                                                 
 650         } catch (FileNotFoundException e) {                                                              
 651             // Ignore                                                                                    
 652         } catch (IOException e) {                                                                        
 653             //noinspection ResultOfMethodCallIgnored                                                     
 654             context.getFileStreamPath(PREFERENCES).delete();                                             
 655         } finally {                                                                                      
 656             if (out != null) {                                                                           
 657                 try {                                                                                    
 658                     out.close();                                                                         
 659                 } catch (IOException e) {                                                                
 660                     // Ignore                                                                            
 661                 }                                                                                        
 662             }                                                                                            
 663         }                                                                                                
 664     }                                                                                                    
 665                                                                                                          
 666     public Stats getStats() {                                                                            
 667         return mStats;                                                                                   
 668     }                                                                                                    
 669                                                                                                          
 670     public LayoutInflater getInflater() {                                                                
 671         return mInflater;                                                                                
 672     }                                                                                                    
 673                                                                                                          
 674     boolean isDraggingEnabled() {                                                                        
 675         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 676         // that is subsequently removed from the workspace in startBinding().                            
 677         return !mModel.isLoadingWorkspace();                                                             
 678     }                                                                                                    
 679                                                                                                          
 680     static int getScreen() {                                                                             
 681         synchronized (sLock) {                                                                           
 682             return sScreen;                                                                              
 683         }                                                                                                
 684     }                                                                                                    
 685                                                                                                          
 686     static void setScreen(int screen) {                                                                  
 687         synchronized (sLock) {                                                                           
 688             sScreen = screen;                                                                            
 689         }                                                                                                
 690     }                                                                                                    
 691                                                                                                          
 692     public static int generateViewId() {                                                                 
 693         if (Build.VERSION.SDK_INT >= 17) {                                                               
 694             return View.generateViewId();                                                                
 695         } else {                                                                                         
 696             // View.generateViewId() is not available. The following fallback logic is a copy            
 697             // of its implementation.                                                                    
 698             for (;;) {                                                                                   
 699                 final int result = sNextGeneratedId.get();                                               
 700                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 701                 int newValue = result + 1;                                                               
 702                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 703                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 704                     return result;                                                                       
 705                 }                                                                                        
 706             }                                                                                            
 707         }                                                                                                
 708     }                                                                                                    
 709                                                                                                          
 710     public int getViewIdForItem(ItemInfo info) {                                                         
 711         // This cast is safe given the > 2B range for int.                                               
 712         int itemId = (int) info.id;                                                                      
 713         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 714             return mItemIdToViewId.get(itemId);                                                          
 715         }                                                                                                
 716         int viewId = generateViewId();                                                                   
 717         mItemIdToViewId.put(itemId, viewId);                                                             
 718         return viewId;                                                                                   
 719     }                                                                                                    
 720                                                                                                          
 721     /**                                                                                                  
 722      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 723      * a configuration step, this allows the proper animations to run after other transitions.           
 724      */                                                                                                  
 725     private long completeAdd(PendingAddArguments args) {                                                 
 726         long screenId = args.screenId;                                                                   
 727         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 728             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 729             // that the drop page actually exists.                                                       
 730             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 731         }                                                                                                
 732                                                                                                          
 733         switch (args.requestCode) {                                                                      
 734             case REQUEST_CREATE_SHORTCUT:                                                                
 735                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 736                         args.cellY);                                                                     
 737                 break;                                                                                   
 738             case REQUEST_CREATE_APPWIDGET:                                                               
 739                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 740                 break;                                                                                   
 741             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 742                 completeRestoreAppWidget(args.appWidgetId);                                              
 743                 break;                                                                                   
 744         }                                                                                                
 745         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 746         // if you turned the screen off and then back while in All Apps, Launcher would not              
 747         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 748         resetAddInfo();                                                                                  
 749         return screenId;                                                                                 
 750     }                                                                                                    
 751                                                                                                          
 752     @Override                                                                                            
 753     protected void onActivityResult(                                                                     
 754             final int requestCode, final int resultCode, final Intent data) {                            
 755         // Reset the startActivity waiting flag                                                          
 756         setWaitingForResult(false);                                                                      
 757         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 758         mPendingAddWidgetId = -1;                                                                        
 759                                                                                                          
 760         Runnable exitSpringLoaded = new Runnable() {                                                     
 761             @Override                                                                                    
 762             public void run() {                                                                          
 763                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 764                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 765             }                                                                                            
 766         };                                                                                               
 767                                                                                                          
 768         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 769             final int appWidgetId = data != null ?                                                       
 770                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 771             if (resultCode == RESULT_CANCELED) {                                                         
 772                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 773                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 774                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 775             } else if (resultCode == RESULT_OK) {                                                        
 776                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 777                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 778             }                                                                                            
 779             return;                                                                                      
 780         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 781             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 782                 mWorkspace.exitOverviewMode(false);                                                      
 783             }                                                                                            
 784             return;                                                                                      
 785         }                                                                                                
 786                                                                                                          
 787         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 788                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 789                                                                                                          
 790         final boolean workspaceLocked = isWorkspaceLocked();                                             
 791         // We have special handling for widgets                                                          
 792         if (isWidgetDrop) {                                                                              
 793             final int appWidgetId;                                                                       
 794             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 795                     : -1;                                                                                
 796             if (widgetId < 0) {                                                                          
 797                 appWidgetId = pendingAddWidgetId;                                                        
 798             } else {                                                                                     
 799                 appWidgetId = widgetId;                                                                  
 800             }                                                                                            
 801                                                                                                          
 802             final int result;                                                                            
 803             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 804                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 805                         "returned from the widget configuration activity.");                             
 806                 result = RESULT_CANCELED;                                                                
 807                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 808                 final Runnable onComplete = new Runnable() {                                             
 809                     @Override                                                                            
 810                     public void run() {                                                                  
 811                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 812                     }                                                                                    
 813                 };                                                                                       
 814                 if (workspaceLocked) {                                                                   
 815                     // No need to remove the empty screen if we're mid-binding, as the                   
 816                     // the bind will not add the empty screen.                                           
 817                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 818                 } else {                                                                                 
 819                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 820                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 821                 }                                                                                        
 822             } else {                                                                                     
 823                 if (!workspaceLocked) {                                                                  
 824                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 825                         // When the screen id represents an actual screen (as opposed to a rank)         
 826                         // we make sure that the drop page actually exists.                              
 827                         mPendingAddInfo.screenId =                                                       
 828                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 829                     }                                                                                    
 830                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 831                                                                                                          
 832                     dropLayout.setDropPending(true);                                                     
 833                     final Runnable onComplete = new Runnable() {                                         
 834                         @Override                                                                        
 835                         public void run() {                                                              
 836                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 837                             dropLayout.setDropPending(false);                                            
 838                         }                                                                                
 839                     };                                                                                   
 840                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 841                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 842                 } else {                                                                                 
 843                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 844                             mPendingAddInfo);                                                            
 845                     sPendingAddItem = args;                                                              
 846                 }                                                                                        
 847             }                                                                                            
 848             return;                                                                                      
 849         }                                                                                                
 850                                                                                                          
 851         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 852             if (resultCode == RESULT_OK) {                                                               
 853                 // Update the widget view.                                                               
 854                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 855                         pendingAddWidgetId, mPendingAddInfo);                                            
 856                 if (workspaceLocked) {                                                                   
 857                     sPendingAddItem = args;                                                              
 858                 } else {                                                                                 
 859                     completeAdd(args);                                                                   
 860                 }                                                                                        
 861             }                                                                                            
 862             // Leave the widget in the pending state if the user canceled the configure.                 
 863             return;                                                                                      
 864         }                                                                                                
 865                                                                                                          
 866         // The pattern used here is that a user PICKs a specific application,                            
 867         // which, depending on the target, might need to CREATE the actual target.                       
 868                                                                                                          
 869         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 870         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 871         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 872             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 873                     mPendingAddInfo);                                                                    
 874             if (isWorkspaceLocked()) {                                                                   
 875                 sPendingAddItem = args;                                                                  
 876             } else {                                                                                     
 877                 completeAdd(args);                                                                       
 878                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 879                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 880             }                                                                                            
 881         } else if (resultCode == RESULT_CANCELED) {                                                      
 882             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 883                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 884         }                                                                                                
 885         mDragLayer.clearAnimatedView();                                                                  
 886     }                                                                                                    
 887                                                                                                          
 888     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 889             appWidgetId, ItemInfo info) {                                                                
 890         PendingAddArguments args = new PendingAddArguments();                                            
 891         args.requestCode = requestCode;                                                                  
 892         args.intent = data;                                                                              
 893         args.container = info.container;                                                                 
 894         args.screenId = info.screenId;                                                                   
 895         args.cellX = info.cellX;                                                                         
 896         args.cellY = info.cellY;                                                                         
 897         args.appWidgetId = appWidgetId;                                                                  
 898         return args;                                                                                     
 899     }                                                                                                    
 900                                                                                                          
 901     /**                                                                                                  
 902      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 903      *                                                                                                   
 904      * @param screenId the screen id to check                                                            
 905      * @return the new screen, or screenId if it exists                                                  
 906      */                                                                                                  
 907     private long ensurePendingDropLayoutExists(long screenId) {                                          
 908         CellLayout dropLayout =                                                                          
 909                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 910         if (dropLayout == null) {                                                                        
 911             // it's possible that the add screen was removed because it was                              
 912             // empty and a re-bind occurred                                                              
 913             mWorkspace.addExtraEmptyScreen();                                                            
 914             return mWorkspace.commitExtraEmptyScreen();                                                  
 915         } else {                                                                                         
 916             return screenId;                                                                             
 917         }                                                                                                
 918     }                                                                                                    
 919                                                                                                          
 920     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 921         CellLayout cellLayout =                                                                          
 922                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 923         Runnable onCompleteRunnable = null;                                                              
 924         int animationType = 0;                                                                           
 925                                                                                                          
 926         AppWidgetHostView boundWidget = null;                                                            
 927         if (resultCode == RESULT_OK) {                                                                   
 928             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 929             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 930                     mPendingAddWidgetInfo);                                                              
 931             boundWidget = layout;                                                                        
 932             onCompleteRunnable = new Runnable() {                                                        
 933                 @Override                                                                                
 934                 public void run() {                                                                      
 935                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 936                             mPendingAddInfo.screenId, layout, null);                                     
 937                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 938                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 939                 }                                                                                        
 940             };                                                                                           
 941         } else if (resultCode == RESULT_CANCELED) {                                                      
 942             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 943             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 944         }                                                                                                
 945         if (mDragLayer.getAnimatedView() != null) {                                                      
 946             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 947                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 948                     animationType, boundWidget, true);                                                   
 949         } else if (onCompleteRunnable != null) {                                                         
 950             // The animated view may be null in the case of a rotation during widget configuration       
 951             onCompleteRunnable.run();                                                                    
 952         }                                                                                                
 953     }                                                                                                    
 954                                                                                                          
 955     @Override                                                                                            
 956     protected void onStop() {                                                                            
 957         super.onStop();                                                                                  
 958         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 959     }                                                                                                    
 960                                                                                                          
 961     @Override                                                                                            
 962     protected void onStart() {                                                                           
 963         super.onStart();                                                                                 
 964         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 965     }                                                                                                    
 966                                                                                                          
 967     @Override                                                                                            
 968     protected void onResume() {                                                                          
 969         long startTime = 0;                                                                              
 970         if (DEBUG_RESUME_TIME) {                                                                         
 971             startTime = System.currentTimeMillis();                                                      
 972             Log.v(TAG, "Launcher.onResume()");                                                           
 973         }                                                                                                
 974         super.onResume();                                                                                
 975                                                                                                          
 976         // Restore the previous launcher state                                                           
 977         if (mOnResumeState == State.WORKSPACE) {                                                         
 978             showWorkspace(false);                                                                        
 979         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                             
 980             showAllApps(false, mAppsCustomizeContent.getContentType(), false);                           
 981         }                                                                                                
 982         mOnResumeState = State.NONE;                                                                     
 983                                                                                                          
 984         // Background was set to gradient in onPause(), restore to black if in all apps.                 
 985         setWorkspaceBackground(mState == State.WORKSPACE);                                               
 986                                                                                                          
 987         mPaused = false;                                                                                 
 988         if (mRestoring || mOnResumeNeedsLoad) {                                                          
 989             setWorkspaceLoading(true);                                                                   
 990             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
 991             mRestoring = false;                                                                          
 992             mOnResumeNeedsLoad = false;                                                                  
 993         }                                                                                                
 994         if (mBindOnResumeCallbacks.size() > 0) {                                                         
 995             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
 996             // execute them here                                                                         
 997             long startTimeCallbacks = 0;                                                                 
 998             if (DEBUG_RESUME_TIME) {                                                                     
 999                 startTimeCallbacks = System.currentTimeMillis();                                         
1000             }                                                                                            
1001                                                                                                          
1002             if (mAppsCustomizeContent != null) {                                                         
1003                 mAppsCustomizeContent.setBulkBind(true);                                                 
1004             }                                                                                            
1005             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1006                 mBindOnResumeCallbacks.get(i).run();                                                     
1007             }                                                                                            
1008             if (mAppsCustomizeContent != null) {                                                         
1009                 mAppsCustomizeContent.setBulkBind(false);                                                
1010             }                                                                                            
1011             mBindOnResumeCallbacks.clear();                                                              
1012             if (DEBUG_RESUME_TIME) {                                                                     
1013                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1014                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1015             }                                                                                            
1016         }                                                                                                
1017         if (mOnResumeCallbacks.size() > 0) {                                                             
1018             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1019                 mOnResumeCallbacks.get(i).run();                                                         
1020             }                                                                                            
1021             mOnResumeCallbacks.clear();                                                                  
1022         }                                                                                                
1023                                                                                                          
1024         // Reset the pressed state of icons that were locked in the press state while activities         
1025         // were launching                                                                                
1026         if (mWaitingForResume != null) {                                                                 
1027             // Resets the previous workspace icon press state                                            
1028             mWaitingForResume.setStayPressed(false);                                                     
1029         }                                                                                                
1030                                                                                                          
1031         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1032         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1033         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1034         // orientation.                                                                                  
1035         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1036                                                                                                          
1037         // Process any items that were added while Launcher was away.                                    
1038         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1039                                                                                                          
1040         // Update the voice search button proxy                                                          
1041         updateVoiceButtonProxyVisible(false);                                                            
1042                                                                                                          
1043         // Again, as with the above scenario, it's possible that one or more of the global icons         
1044         // were updated in the wrong orientation.                                                        
1045         updateGlobalIcons();                                                                             
1046         if (DEBUG_RESUME_TIME) {                                                                         
1047             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1048         }                                                                                                
1049                                                                                                          
1050         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1051             // If we are resuming and the custom content is the current page, we call onShow().          
1052             // It is also poassible that onShow will instead be called slightly after first layout       
1053             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1054             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1055                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1056             }                                                                                            
1057         }                                                                                                
1058         mWorkspace.updateInteractionForState();                                                          
1059         mWorkspace.onResume();                                                                           
1060                                                                                                          
1061         PackageInstallerCompat.getInstance(this).onResume();                                             
1062     }                                                                                                    
1063                                                                                                          
1064     @Override                                                                                            
1065     protected void onPause() {                                                                           
1066         // Ensure that items added to Launcher are queued until Launcher returns                         
1067         InstallShortcutReceiver.enableInstallQueue();                                                    
1068         PackageInstallerCompat.getInstance(this).onPause();                                              
1069                                                                                                          
1070         super.onPause();                                                                                 
1071         mPaused = true;                                                                                  
1072         mDragController.cancelDrag();                                                                    
1073         mDragController.resetLastGestureUpTime();                                                        
1074                                                                                                          
1075         // We call onHide() aggressively. The custom content callbacks should be able to                 
1076         // debounce excess onHide calls.                                                                 
1077         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1078             mWorkspace.getCustomContentCallbacks().onHide();                                             
1079         }                                                                                                
1080     }                                                                                                    
1081                                                                                                          
1082     QSBScroller mQsbScroller = new QSBScroller() {                                                       
1083         int scrollY = 0;                                                                                 
1084                                                                                                          
1085         @Override                                                                                        
1086         public void setScrollY(int scroll) {                                                             
1087             scrollY = scroll;                                                                            
1088                                                                                                          
1089             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1090                 mSearchDropTargetBar.setTranslationY(- scrollY);                                         
1091                 getQsbBar().setTranslationY(-scrollY);                                                   
1092             }                                                                                            
1093         }                                                                                                
1094     };                                                                                                   
1095                                                                                                          
1096     public void resetQSBScroll() {                                                                       
1097         mSearchDropTargetBar.animate().translationY(0).start();                                          
1098         getQsbBar().animate().translationY(0).start();                                                   
1099     }                                                                                                    
1100                                                                                                          
1101     public interface CustomContentCallbacks {                                                            
1102         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1103         // by a onResume or by scrolling otherwise.                                                      
1104         public void onShow(boolean fromResume);                                                          
1105                                                                                                          
1106         // Custom content is completely hidden                                                           
1107         public void onHide();                                                                            
1108                                                                                                          
1109         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1110         public void onScrollProgressChanged(float progress);                                             
1111                                                                                                          
1112         // Indicates whether the user is allowed to scroll away from the custom content.                 
1113         boolean isScrollingAllowed();                                                                    
1114     }                                                                                                    
1115                                                                                                          
1116     protected boolean hasSettings() {                                                                    
1117         return false;                                                                                    
1118     }                                                                                                    
1119                                                                                                          
1120     public interface QSBScroller {                                                                       
1121         public void setScrollY(int scrollY);                                                             
1122     }                                                                                                    
1123                                                                                                          
1124     public QSBScroller addToCustomContentPage(View customContent,                                        
1125             CustomContentCallbacks callbacks, String description) {                                      
1126         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1127         return mQsbScroller;                                                                             
1128     }                                                                                                    
1129                                                                                                          
1130     // The custom content needs to offset its content to account for the QSB                             
1131     public int getTopOffsetForCustomContent() {                                                          
1132         return mWorkspace.getPaddingTop();                                                               
1133     }                                                                                                    
1134                                                                                                          
1135     @Override                                                                                            
1136     public Object onRetainNonConfigurationInstance() {                                                   
1137         // Flag the loader to stop early before switching                                                
1138         if (mModel.isCurrentCallbacks(this)) {                                                           
1139             mModel.stopLoader();                                                                         
1140         }                                                                                                
1141         if (mAppsCustomizeContent != null) {                                                             
1142             mAppsCustomizeContent.surrender();                                                           
1143         }                                                                                                
1144         return Boolean.TRUE;                                                                             
1145     }                                                                                                    
1146                                                                                                          
1147     // We can't hide the IME if it was forced open.  So don't bother                                     
1148     @Override                                                                                            
1149     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1150         super.onWindowFocusChanged(hasFocus);                                                            
1151         mHasFocus = hasFocus;                                                                            
1152     }                                                                                                    
1153                                                                                                          
1154     private boolean acceptFilter() {                                                                     
1155         final InputMethodManager inputManager = (InputMethodManager)                                     
1156                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1157         return !inputManager.isFullscreenMode();                                                         
1158     }                                                                                                    
1159                                                                                                          
1160     @Override                                                                                            
1161     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1162         final int uniChar = event.getUnicodeChar();                                                      
1163         final boolean handled = super.onKeyDown(keyCode, event);                                         
1164         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1165         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1166             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1167                     keyCode, event);                                                                     
1168             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1169                 // something usable has been typed - start a search                                      
1170                 // the typed text will be retrieved and cleared by                                       
1171                 // showSearchDialog()                                                                    
1172                 // If there are multiple keystrokes before the search dialog takes focus,                
1173                 // onSearchRequested() will be called for every keystroke,                               
1174                 // but it is idempotent, so it's fine.                                                   
1175                 return onSearchRequested();                                                              
1176             }                                                                                            
1177         }                                                                                                
1178                                                                                                          
1179         // Eat the long press event so the keyboard doesn't come up.                                     
1180         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1181             return true;                                                                                 
1182         }                                                                                                
1183                                                                                                          
1184         return handled;                                                                                  
1185     }                                                                                                    
1186                                                                                                          
1187     private String getTypedText() {                                                                      
1188         return mDefaultKeySsb.toString();                                                                
1189     }                                                                                                    
1190                                                                                                          
1191     private void clearTypedText() {                                                                      
1192         mDefaultKeySsb.clear();                                                                          
1193         mDefaultKeySsb.clearSpans();                                                                     
1194         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1195     }                                                                                                    
1196                                                                                                          
1197     /**                                                                                                  
1198      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1199      * State                                                                                             
1200      */                                                                                                  
1201     private static State intToState(int stateOrdinal) {                                                  
1202         State state = State.WORKSPACE;                                                                   
1203         final State[] stateValues = State.values();                                                      
1204         for (int i = 0; i < stateValues.length; i++) {                                                   
1205             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1206                 state = stateValues[i];                                                                  
1207                 break;                                                                                   
1208             }                                                                                            
1209         }                                                                                                
1210         return state;                                                                                    
1211     }                                                                                                    
1212                                                                                                          
1213     /**                                                                                                  
1214      * Restores the previous state, if it exists.                                                        
1215      *                                                                                                   
1216      * @param savedState The previous state.                                                             
1217      */                                                                                                  
1218     @SuppressWarnings("unchecked")                                                                       
1219     private void restoreState(Bundle savedState) {                                                       
1220         if (savedState == null) {                                                                        
1221             return;                                                                                      
1222         }                                                                                                
1223                                                                                                          
1224         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1225         if (state == State.APPS_CUSTOMIZE) {                                                             
1226             mOnResumeState = State.APPS_CUSTOMIZE;                                                       
1227         }                                                                                                
1228                                                                                                          
1229         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1230                 PagedView.INVALID_RESTORE_PAGE);                                                         
1231         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1232             mWorkspace.setRestorePage(currentScreen);                                                    
1233         }                                                                                                
1234                                                                                                          
1235         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1236         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1237                                                                                                          
1238         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1239             mPendingAddInfo.container = pendingAddContainer;                                             
1240             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1241             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1242             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1243             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1244             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1245             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1246             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1247             setWaitingForResult(true);                                                                   
1248             mRestoring = true;                                                                           
1249         }                                                                                                
1250                                                                                                          
1251         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1252         if (renameFolder) {                                                                              
1253             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1254             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1255             mRestoring = true;                                                                           
1256         }                                                                                                
1257                                                                                                          
1258         // Restore the AppsCustomize tab                                                                 
1259         if (mAppsCustomizeTabHost != null) {                                                             
1260             String curTab = savedState.getString("apps_customize_currentTab");                           
1261             if (curTab != null) {                                                                        
1262                 mAppsCustomizeTabHost.setContentTypeImmediate(                                           
1263                         mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                          
1264                 mAppsCustomizeContent.loadAssociatedPages(                                               
1265                         mAppsCustomizeContent.getCurrentPage());                                         
1266             }                                                                                            
1267                                                                                                          
1268             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1269             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1270         }                                                                                                
1271         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1272                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1273     }                                                                                                    
1274                                                                                                          
1275     /**                                                                                                  
1276      * Finds all the views we need and configure them properly.                                          
1277      */                                                                                                  
1278     private void setupViews() {                                                                          
1279         final DragController dragController = mDragController;                                           
1280                                                                                                          
1281         mLauncherView = findViewById(R.id.launcher);                                                     
1282         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1283         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1284         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1285         mWorkspace.setPageSwitchListener(this);                                                          
1286         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1287                                                                                                          
1288         mLauncherView.setSystemUiVisibility(                                                             
1289                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1290         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1291                                                                                                          
1292         // Setup the drag layer                                                                          
1293         mDragLayer.setup(this, dragController);                                                          
1294                                                                                                          
1295         // Setup the hotseat                                                                             
1296         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1297         if (mHotseat != null) {                                                                          
1298             mHotseat.setup(this);                                                                        
1299             mHotseat.setOnLongClickListener(this);                                                       
1300         }                                                                                                
1301                                                                                                          
1302         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1303         View widgetButton = findViewById(R.id.widget_button);                                            
1304         widgetButton.setOnClickListener(new OnClickListener() {                                          
1305             @Override                                                                                    
1306             public void onClick(View arg0) {                                                             
1307                 if (!mWorkspace.isSwitchingState()) {                                                    
1308                     onClickAddWidgetButton(arg0);                                                        
1309                 }                                                                                        
1310             }                                                                                            
1311         });                                                                                              
1312         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1313                                                                                                          
1314         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1315         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1316             @Override                                                                                    
1317             public void onClick(View arg0) {                                                             
1318                 if (!mWorkspace.isSwitchingState()) {                                                    
1319                     onClickWallpaperPicker(arg0);                                                        
1320                 }                                                                                        
1321             }                                                                                            
1322         });                                                                                              
1323         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1324                                                                                                          
1325         View settingsButton = findViewById(R.id.settings_button);                                        
1326         if (hasSettings()) {                                                                             
1327             settingsButton.setOnClickListener(new OnClickListener() {                                    
1328                 @Override                                                                                
1329                 public void onClick(View arg0) {                                                         
1330                     if (!mWorkspace.isSwitchingState()) {                                                
1331                         onClickSettingsButton(arg0);                                                     
1332                     }                                                                                    
1333                 }                                                                                        
1334             });                                                                                          
1335             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1336         } else {                                                                                         
1337             settingsButton.setVisibility(View.GONE);                                                     
1338             FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();     
1339             lp.gravity = Gravity.END | Gravity.TOP;                                                      
1340             widgetButton.requestLayout();                                                                
1341         }                                                                                                
1342                                                                                                          
1343         mOverviewPanel.setAlpha(0f);                                                                     
1344                                                                                                          
1345         // Setup the workspace                                                                           
1346         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1347         mWorkspace.setOnLongClickListener(this);                                                         
1348         mWorkspace.setup(dragController);                                                                
1349         dragController.addDragListener(mWorkspace);                                                      
1350                                                                                                          
1351         // Get the search/delete bar                                                                     
1352         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1353                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1354                                                                                                          
1355         // Setup AppsCustomize                                                                           
1356         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);           
1357         mAppsCustomizeContent = (AppsCustomizePagedView)                                                 
1358                 mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                    
1359         mAppsCustomizeContent.setup(this, dragController);                                               
1360                                                                                                          
1361         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1362         dragController.setDragScoller(mWorkspace);                                                       
1363         dragController.setScrollView(mDragLayer);                                                        
1364         dragController.setMoveTarget(mWorkspace);                                                        
1365         dragController.addDropTarget(mWorkspace);                                                        
1366         if (mSearchDropTargetBar != null) {                                                              
1367             mSearchDropTargetBar.setup(this, dragController);                                            
1368         }                                                                                                
1369                                                                                                          
1370         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1371             Log.v(TAG, "adding WeightWatcher");                                                          
1372             mWeightWatcher = new WeightWatcher(this);                                                    
1373             mWeightWatcher.setAlpha(0.5f);                                                               
1374             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1375                     new FrameLayout.LayoutParams(                                                        
1376                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1377                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1378                             Gravity.BOTTOM)                                                              
1379             );                                                                                           
1380                                                                                                          
1381             boolean show = shouldShowWeightWatcher();                                                    
1382             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1383         }                                                                                                
1384     }                                                                                                    
1385                                                                                                          
1386     /**                                                                                                  
1387      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1388      */                                                                                                  
1389     public void setAllAppsButton(View allAppsButton) {                                                   
1390         mAllAppsButton = allAppsButton;                                                                  
1391     }                                                                                                    
1392                                                                                                          
1393     public View getAllAppsButton() {                                                                     
1394         return mAllAppsButton;                                                                           
1395     }                                                                                                    
1396                                                                                                          
1397     /**                                                                                                  
1398      * Creates a view representing a shortcut.                                                           
1399      *                                                                                                   
1400      * @param info The data structure describing the shortcut.                                           
1401      *                                                                                                   
1402      * @return A View inflated from R.layout.application.                                                
1403      */                                                                                                  
1404     View createShortcut(ShortcutInfo info) {                                                             
1405         return createShortcut(R.layout.application,                                                      
1406                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1407     }                                                                                                    
1408                                                                                                          
1409     /**                                                                                                  
1410      * Creates a view representing a shortcut inflated from the specified resource.                      
1411      *                                                                                                   
1412      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1413      * @param parent The group the shortcut belongs to.                                                  
1414      * @param info The data structure describing the shortcut.                                           
1415      *                                                                                                   
1416      * @return A View inflated from layoutResId.                                                         
1417      */                                                                                                  
1418     View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                          
1419         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1420         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1421         favorite.setOnClickListener(this);                                                               
1422         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1423         return favorite;                                                                                 
1424     }                                                                                                    
1425                                                                                                          
1426     /**                                                                                                  
1427      * Add a shortcut to the workspace.                                                                  
1428      *                                                                                                   
1429      * @param data The intent describing the shortcut.                                                   
1430      * @param cellInfo The position on screen where to create the shortcut.                              
1431      */                                                                                                  
1432     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1433             int cellY) {                                                                                 
1434         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1435         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1436         CellLayout layout = getCellLayout(container, screenId);                                          
1437                                                                                                          
1438         boolean foundCellSpan = false;                                                                   
1439                                                                                                          
1440         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                             
1441         if (info == null) {                                                                              
1442             return;                                                                                      
1443         }                                                                                                
1444         final View view = createShortcut(info);                                                          
1445                                                                                                          
1446         // First we check if we already know the exact location where we want to add this item.          
1447         if (cellX >= 0 && cellY >= 0) {                                                                  
1448             cellXY[0] = cellX;                                                                           
1449             cellXY[1] = cellY;                                                                           
1450             foundCellSpan = true;                                                                        
1451                                                                                                          
1452             // If appropriate, either create a folder or add to an existing folder                       
1453             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1454                     true, null,null)) {                                                                  
1455                 return;                                                                                  
1456             }                                                                                            
1457             DragObject dragObject = new DragObject();                                                    
1458             dragObject.dragInfo = info;                                                                  
1459             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1460                     true)) {                                                                             
1461                 return;                                                                                  
1462             }                                                                                            
1463         } else if (touchXY != null) {                                                                    
1464             // when dragging and dropping, just find the closest free spot                               
1465             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1466             foundCellSpan = (result != null);                                                            
1467         } else {                                                                                         
1468             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1469         }                                                                                                
1470                                                                                                          
1471         if (!foundCellSpan) {                                                                            
1472             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1473             return;                                                                                      
1474         }                                                                                                
1475                                                                                                          
1476         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1477                                                                                                          
1478         if (!mRestoring) {                                                                               
1479             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1480                     isWorkspaceLocked());                                                                
1481         }                                                                                                
1482     }                                                                                                    
1483                                                                                                          
1484     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1485             int minHeight) {                                                                             
1486         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1487         // We want to account for the extra amount of padding that we are adding to the widget           
1488         // to ensure that it gets the full amount of space that it has requested                         
1489         int requiredWidth = minWidth + padding.left + padding.right;                                     
1490         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1491         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1492     }                                                                                                    
1493                                                                                                          
1494     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1495         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1496     }                                                                                                    
1497                                                                                                          
1498     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1499         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1500     }                                                                                                    
1501                                                                                                          
1502     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1503         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1504     }                                                                                                    
1505                                                                                                          
1506     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1507         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1508                 info.minResizeHeight);                                                                   
1509     }                                                                                                    
1510                                                                                                          
1511     /**                                                                                                  
1512      * Add a widget to the workspace.                                                                    
1513      *                                                                                                   
1514      * @param appWidgetId The app widget id                                                              
1515      * @param cellInfo The position on screen where to create the widget.                                
1516      */                                                                                                  
1517     private void completeAddAppWidget(final int appWidgetId, long container, long screenId,              
1518             AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                           
1519         if (appWidgetInfo == null) {                                                                     
1520             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
1521         }                                                                                                
1522                                                                                                          
1523         // Calculate the grid spans needed to fit this widget                                            
1524         CellLayout layout = getCellLayout(container, screenId);                                          
1525                                                                                                          
1526         int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                      
1527         int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                            
1528                                                                                                          
1529         // Try finding open space on Launcher screen                                                     
1530         // We have saved the position to which the widget was dragged-- this really only matters         
1531         // if we are placing widgets on a "spring-loaded" screen                                         
1532         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1533         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1534         int[] finalSpan = new int[2];                                                                    
1535         boolean foundCellSpan = false;                                                                   
1536         if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                  
1537             cellXY[0] = mPendingAddInfo.cellX;                                                           
1538             cellXY[1] = mPendingAddInfo.cellY;                                                           
1539             spanXY[0] = mPendingAddInfo.spanX;                                                           
1540             spanXY[1] = mPendingAddInfo.spanY;                                                           
1541             foundCellSpan = true;                                                                        
1542         } else if (touchXY != null) {                                                                    
1543             // when dragging and dropping, just find the closest free spot                               
1544             int[] result = layout.findNearestVacantArea(                                                 
1545                     touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                       
1546                     spanXY[1], cellXY, finalSpan);                                                       
1547             spanXY[0] = finalSpan[0];                                                                    
1548             spanXY[1] = finalSpan[1];                                                                    
1549             foundCellSpan = (result != null);                                                            
1550         } else {                                                                                         
1551             foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                  
1552         }                                                                                                
1553                                                                                                          
1554         if (!foundCellSpan) {                                                                            
1555             if (appWidgetId != -1) {                                                                     
1556                 // Deleting an app widget ID is a void call but writes to disk before returning          
1557                 // to the caller...                                                                      
1558                 new AsyncTask<Void, Void, Void>() {                                                      
1559                     public Void doInBackground(Void ... args) {                                          
1560                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                   
1561                         return null;                                                                     
1562                     }                                                                                    
1563                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                        
1564             }                                                                                            
1565             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1566             return;                                                                                      
1567         }                                                                                                
1568                                                                                                          
1569         // Build Launcher-specific widget info and save to database                                      
1570         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                      
1571                 appWidgetInfo.provider);                                                                 
1572         launcherInfo.spanX = spanXY[0];                                                                  
1573         launcherInfo.spanY = spanXY[1];                                                                  
1574         launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                
1575         launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                
1576         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1577                                                                                                          
1578         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1579                 container, screenId, cellXY[0], cellXY[1], false);                                       
1580                                                                                                          
1581         if (!mRestoring) {                                                                               
1582             if (hostView == null) {                                                                      
1583                 // Perform actual inflation because we're live                                           
1584                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1585                 launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                          
1586             } else {                                                                                     
1587                 // The AppWidgetHostView has already been inflated and instantiated                      
1588                 launcherInfo.hostView = hostView;                                                        
1589             }                                                                                            
1590                                                                                                          
1591             launcherInfo.hostView.setTag(launcherInfo);                                                  
1592             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1593             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1594                                                                                                          
1595             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],     
1596                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                        
1597                                                                                                          
1598             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1599         }                                                                                                
1600         resetAddInfo();                                                                                  
1601     }                                                                                                    
1602                                                                                                          
1603     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1604         @Override                                                                                        
1605         public void onReceive(Context context, Intent intent) {                                          
1606             final String action = intent.getAction();                                                    
1607             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1608                 mUserPresent = false;                                                                    
1609                 mDragLayer.clearAllResizeFrames();                                                       
1610                 updateRunning();                                                                         
1611                                                                                                          
1612                 // Reset AllApps to its initial state only if we are not in the middle of                
1613                 // processing a multi-step drop                                                          
1614                 if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {      
1615                     showWorkspace(false);                                                                
1616                 }                                                                                        
1617             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1618                 mUserPresent = true;                                                                     
1619                 updateRunning();                                                                         
1620             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1621                 mModel.resetLoadedState(false, true);                                                    
1622                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1623                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1624             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1625                 mModel.resetLoadedState(false, true);                                                    
1626                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1627                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1628                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1629             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1630                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1631                 getModel().forceReload();                                                                
1632             }                                                                                            
1633         }                                                                                                
1634     };                                                                                                   
1635                                                                                                          
1636     @Override                                                                                            
1637     public void onAttachedToWindow() {                                                                   
1638         super.onAttachedToWindow();                                                                      
1639                                                                                                          
1640         // Listen for broadcasts related to user-presence                                                
1641         final IntentFilter filter = new IntentFilter();                                                  
1642         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1643         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1644         // For handling managed profiles                                                                 
1645         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1646         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1647         if (ENABLE_DEBUG_INTENTS) {                                                                      
1648             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1649             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1650         }                                                                                                
1651         registerReceiver(mReceiver, filter);                                                             
1652         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1653         setupTransparentSystemBarsForLmp();                                                              
1654         mAttached = true;                                                                                
1655         mVisible = true;                                                                                 
1656     }                                                                                                    
1657                                                                                                          
1658     /**                                                                                                  
1659      * Sets up transparent navigation and status bars in LMP.                                            
1660      * This method is a no-op for other platform versions.                                               
1661      */                                                                                                  
1662     @TargetApi(19)                                                                                       
1663     private void setupTransparentSystemBarsForLmp() {                                                    
1664         // TODO(sansid): use the APIs directly when compiling against L sdk.                             
1665         // Currently we use reflection to access the flags and the API to set the transparency           
1666         // on the System bars.                                                                           
1667         if (Utilities.isLmpOrAbove()) {                                                                  
1668             try {                                                                                        
1669                 getWindow().getAttributes().systemUiVisibility |=                                        
1670                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1671                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1672                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1673                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                
1674                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1675                 Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(              
1676                         "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                            
1677                 getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                             
1678                                                                                                          
1679                 Method setStatusBarColorMethod =                                                         
1680                         Window.class.getDeclaredMethod("setStatusBarColor", int.class);                  
1681                 Method setNavigationBarColorMethod =                                                     
1682                         Window.class.getDeclaredMethod("setNavigationBarColor", int.class);              
1683                 setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                          
1684                 setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                      
1685             } catch (NoSuchFieldException e) {                                                           
1686                 Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                    
1687             } catch (NoSuchMethodException ex) {                                                         
1688                 Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                   
1689             } catch (IllegalAccessException e) {                                                         
1690                 Log.w(TAG, "IllegalAccessException while setting up transparent bars");                  
1691             } catch (IllegalArgumentException e) {                                                       
1692                 Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                
1693             } catch (InvocationTargetException e) {                                                      
1694                 Log.w(TAG, "InvocationTargetException while setting up transparent bars");               
1695             } finally {}                                                                                 
1696         }                                                                                                
1697     }                                                                                                    
1698                                                                                                          
1699     @Override                                                                                            
1700     public void onDetachedFromWindow() {                                                                 
1701         super.onDetachedFromWindow();                                                                    
1702         mVisible = false;                                                                                
1703                                                                                                          
1704         if (mAttached) {                                                                                 
1705             unregisterReceiver(mReceiver);                                                               
1706             mAttached = false;                                                                           
1707         }                                                                                                
1708         updateRunning();                                                                                 
1709     }                                                                                                    
1710                                                                                                          
1711     public void onWindowVisibilityChanged(int visibility) {                                              
1712         mVisible = visibility == View.VISIBLE;                                                           
1713         updateRunning();                                                                                 
1714         // The following code used to be in onResume, but it turns out onResume is called when           
1715         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1716         // is a more appropriate event to handle                                                         
1717         if (mVisible) {                                                                                  
1718             mAppsCustomizeTabHost.onWindowVisible();                                                     
1719             if (!mWorkspaceLoading) {                                                                    
1720                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1721                 // We want to let Launcher draw itself at least once before we force it to build         
1722                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1723                 // apps is nice and speedy.                                                              
1724                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1725                     private boolean mStarted = false;                                                    
1726                     public void onDraw() {                                                               
1727                         if (mStarted) return;                                                            
1728                         mStarted = true;                                                                 
1729                         // We delay the layer building a bit in order to give                            
1730                         // other message processing a time to run.  In particular                        
1731                         // this avoids a delay in hiding the IME if it was                               
1732                         // currently shown, because doing that may involve                               
1733                         // some communication back with the app.                                         
1734                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1735                         final ViewTreeObserver.OnDrawListener listener = this;                           
1736                         mWorkspace.post(new Runnable() {                                                 
1737                                 public void run() {                                                      
1738                                     if (mWorkspace != null &&                                            
1739                                             mWorkspace.getViewTreeObserver() != null) {                  
1740                                         mWorkspace.getViewTreeObserver().                                
1741                                                 removeOnDrawListener(listener);                          
1742                                     }                                                                    
1743                                 }                                                                        
1744                             });                                                                          
1745                         return;                                                                          
1746                     }                                                                                    
1747                 });                                                                                      
1748             }                                                                                            
1749             clearTypedText();                                                                            
1750         }                                                                                                
1751     }                                                                                                    
1752                                                                                                          
1753     private void sendAdvanceMessage(long delay) {                                                        
1754         mHandler.removeMessages(ADVANCE_MSG);                                                            
1755         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1756         mHandler.sendMessageDelayed(msg, delay);                                                         
1757         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1758     }                                                                                                    
1759                                                                                                          
1760     private void updateRunning() {                                                                       
1761         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1762         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1763             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1764             if (autoAdvanceRunning) {                                                                    
1765                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1766                 sendAdvanceMessage(delay);                                                               
1767             } else {                                                                                     
1768                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1769                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1770                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1771                 }                                                                                        
1772                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1773                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1774             }                                                                                            
1775         }                                                                                                
1776     }                                                                                                    
1777                                                                                                          
1778     private final Handler mHandler = new Handler() {                                                     
1779         @Override                                                                                        
1780         public void handleMessage(Message msg) {                                                         
1781             if (msg.what == ADVANCE_MSG) {                                                               
1782                 int i = 0;                                                                               
1783                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1784                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1785                     final int delay = mAdvanceStagger * i;                                               
1786                     if (v instanceof Advanceable) {                                                      
1787                        postDelayed(new Runnable() {                                                      
1788                            public void run() {                                                           
1789                                ((Advanceable) v).advance();                                              
1790                            }                                                                             
1791                        }, delay);                                                                        
1792                     }                                                                                    
1793                     i++;                                                                                 
1794                 }                                                                                        
1795                 sendAdvanceMessage(mAdvanceInterval);                                                    
1796             }                                                                                            
1797         }                                                                                                
1798     };                                                                                                   
1799                                                                                                          
1800     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1801         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1802         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1803         if (v instanceof Advanceable) {                                                                  
1804             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1805             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1806             updateRunning();                                                                             
1807         }                                                                                                
1808     }                                                                                                    
1809                                                                                                          
1810     void removeWidgetToAutoAdvance(View hostView) {                                                      
1811         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1812             mWidgetsToAdvance.remove(hostView);                                                          
1813             updateRunning();                                                                             
1814         }                                                                                                
1815     }                                                                                                    
1816                                                                                                          
1817     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1818         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1819         launcherInfo.hostView = null;                                                                    
1820     }                                                                                                    
1821                                                                                                          
1822     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1823         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1824         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1825     }                                                                                                    
1826                                                                                                          
1827     public DragLayer getDragLayer() {                                                                    
1828         return mDragLayer;                                                                               
1829     }                                                                                                    
1830                                                                                                          
1831     public Workspace getWorkspace() {                                                                    
1832         return mWorkspace;                                                                               
1833     }                                                                                                    
1834                                                                                                          
1835     public Hotseat getHotseat() {                                                                        
1836         return mHotseat;                                                                                 
1837     }                                                                                                    
1838                                                                                                          
1839     public ViewGroup getOverviewPanel() {                                                                
1840         return mOverviewPanel;                                                                           
1841     }                                                                                                    
1842                                                                                                          
1843     public SearchDropTargetBar getSearchBar() {                                                          
1844         return mSearchDropTargetBar;                                                                     
1845     }                                                                                                    
1846                                                                                                          
1847     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1848         return mAppWidgetHost;                                                                           
1849     }                                                                                                    
1850                                                                                                          
1851     public LauncherModel getModel() {                                                                    
1852         return mModel;                                                                                   
1853     }                                                                                                    
1854                                                                                                          
1855     protected SharedPreferences getSharedPrefs() {                                                       
1856         return mSharedPrefs;                                                                             
1857     }                                                                                                    
1858                                                                                                          
1859     public void closeSystemDialogs() {                                                                   
1860         getWindow().closeAllPanels();                                                                    
1861                                                                                                          
1862         // Whatever we were doing is hereby canceled.                                                    
1863         setWaitingForResult(false);                                                                      
1864     }                                                                                                    
1865                                                                                                          
1866     @Override                                                                                            
1867     protected void onNewIntent(Intent intent) {                                                          
1868         long startTime = 0;                                                                              
1869         if (DEBUG_RESUME_TIME) {                                                                         
1870             startTime = System.currentTimeMillis();                                                      
1871         }                                                                                                
1872         super.onNewIntent(intent);                                                                       
1873                                                                                                          
1874         // Close the menu                                                                                
1875         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1876             // also will cancel mWaitingForResult.                                                       
1877             closeSystemDialogs();                                                                        
1878                                                                                                          
1879             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1880                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1881                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1882                                                                                                          
1883             if (mWorkspace == null) {                                                                    
1884                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1885                 return;                                                                                  
1886             }                                                                                            
1887             Folder openFolder = mWorkspace.getOpenFolder();                                              
1888             // In all these cases, only animate if we're already on home                                 
1889             mWorkspace.exitWidgetResizeMode();                                                           
1890             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1891                     openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                     
1892                 mWorkspace.moveToDefaultScreen(true);                                                    
1893             }                                                                                            
1894                                                                                                          
1895             closeFolder();                                                                               
1896             exitSpringLoadedDragMode();                                                                  
1897                                                                                                          
1898             // If we are already on home, then just animate back to the workspace,                       
1899             // otherwise, just wait until onResume to set the state back to Workspace                    
1900             if (alreadyOnHome) {                                                                         
1901                 showWorkspace(true);                                                                     
1902             } else {                                                                                     
1903                 mOnResumeState = State.WORKSPACE;                                                        
1904             }                                                                                            
1905                                                                                                          
1906             final View v = getWindow().peekDecorView();                                                  
1907             if (v != null && v.getWindowToken() != null) {                                               
1908                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1909                         INPUT_METHOD_SERVICE);                                                           
1910                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1911             }                                                                                            
1912                                                                                                          
1913             // Reset the apps customize page                                                             
1914             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1915                 mAppsCustomizeTabHost.reset();                                                           
1916             }                                                                                            
1917                                                                                                          
1918             onHomeIntent();                                                                              
1919         }                                                                                                
1920                                                                                                          
1921         if (DEBUG_RESUME_TIME) {                                                                         
1922             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1923         }                                                                                                
1924     }                                                                                                    
1925                                                                                                          
1926     /**                                                                                                  
1927      * Override point for subclasses to prevent movement to the default screen when the home             
1928      * button is pressed. Used (for example) in GEL, to prevent movement during a search.                
1929      */                                                                                                  
1930     protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                          
1931         return true;                                                                                     
1932     }                                                                                                    
1933                                                                                                          
1934     /**                                                                                                  
1935      * Override point for subclasses to provide custom behaviour for when a home intent is fired.        
1936      */                                                                                                  
1937     protected void onHomeIntent() {                                                                      
1938         // Do nothing                                                                                    
1939     }                                                                                                    
1940                                                                                                          
1941     @Override                                                                                            
1942     public void onRestoreInstanceState(Bundle state) {                                                   
1943         super.onRestoreInstanceState(state);                                                             
1944         for (int page: mSynchronouslyBoundPages) {                                                       
1945             mWorkspace.restoreInstanceStateForChild(page);                                               
1946         }                                                                                                
1947     }                                                                                                    
1948                                                                                                          
1949     @Override                                                                                            
1950     protected void onSaveInstanceState(Bundle outState) {                                                
1951         if (mWorkspace.getChildCount() > 0) {                                                            
1952             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1953                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1954         }                                                                                                
1955         super.onSaveInstanceState(outState);                                                             
1956                                                                                                          
1957         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1958         // We close any open folder since it will not be re-opened, and we need to make sure             
1959         // this state is reflected.                                                                      
1960         closeFolder();                                                                                   
1961                                                                                                          
1962         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1963                 mWaitingForResult) {                                                                     
1964             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1965             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1966             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1967             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1968             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1969             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1970             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1971             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1972         }                                                                                                
1973                                                                                                          
1974         if (mFolderInfo != null && mWaitingForResult) {                                                  
1975             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
1976             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
1977         }                                                                                                
1978                                                                                                          
1979         // Save the current AppsCustomize tab                                                            
1980         if (mAppsCustomizeTabHost != null) {                                                             
1981             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
1982             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
1983             if (currentTabTag != null) {                                                                 
1984                 outState.putString("apps_customize_currentTab", currentTabTag);                          
1985             }                                                                                            
1986             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
1987             outState.putInt("apps_customize_currentIndex", currentIndex);                                
1988         }                                                                                                
1989         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1990     }                                                                                                    
1991                                                                                                          
1992     @Override                                                                                            
1993     public void onDestroy() {                                                                            
1994         super.onDestroy();                                                                               
1995                                                                                                          
1996         // Remove all pending runnables                                                                  
1997         mHandler.removeMessages(ADVANCE_MSG);                                                            
1998         mHandler.removeMessages(0);                                                                      
1999         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2000                                                                                                          
2001         // Stop callbacks from LauncherModel                                                             
2002         LauncherAppState app = (LauncherAppState.getInstance());                                         
2003                                                                                                          
2004         // It's possible to receive onDestroy after a new Launcher activity has                          
2005         // been created. In this case, don't interfere with the new Launcher.                            
2006         if (mModel.isCurrentCallbacks(this)) {                                                           
2007             mModel.stopLoader();                                                                         
2008             app.setLauncher(null);                                                                       
2009         }                                                                                                
2010                                                                                                          
2011         try {                                                                                            
2012             mAppWidgetHost.stopListening();                                                              
2013         } catch (NullPointerException ex) {                                                              
2014             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2015         }                                                                                                
2016         mAppWidgetHost = null;                                                                           
2017                                                                                                          
2018         mWidgetsToAdvance.clear();                                                                       
2019                                                                                                          
2020         TextKeyListener.getInstance().release();                                                         
2021                                                                                                          
2022         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2023         // to prevent leaking Launcher activities on orientation change.                                 
2024         if (mModel != null) {                                                                            
2025             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2026         }                                                                                                
2027                                                                                                          
2028         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2029         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2030                                                                                                          
2031         mDragLayer.clearAllResizeFrames();                                                               
2032         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2033         mWorkspace.removeAllWorkspaceScreens();                                                          
2034         mWorkspace = null;                                                                               
2035         mDragController = null;                                                                          
2036                                                                                                          
2037         PackageInstallerCompat.getInstance(this).onStop();                                               
2038         LauncherAnimUtils.onDestroyActivity();                                                           
2039     }                                                                                                    
2040                                                                                                          
2041     public DragController getDragController() {                                                          
2042         return mDragController;                                                                          
2043     }                                                                                                    
2044                                                                                                          
2045     @Override                                                                                            
2046     public void startActivityForResult(Intent intent, int requestCode) {                                 
2047         if (requestCode >= 0) {                                                                          
2048             setWaitingForResult(true);                                                                   
2049         }                                                                                                
2050         super.startActivityForResult(intent, requestCode);                                               
2051     }                                                                                                    
2052                                                                                                          
2053     /**                                                                                                  
2054      * Indicates that we want global search for this activity by setting the globalSearch                
2055      * argument for {@link #startSearch} to true.                                                        
2056      */                                                                                                  
2057     @Override                                                                                            
2058     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2059             Bundle appSearchData, boolean globalSearch) {                                                
2060                                                                                                          
2061         showWorkspace(true);                                                                             
2062                                                                                                          
2063         if (initialQuery == null) {                                                                      
2064             // Use any text typed in the launcher as the initial query                                   
2065             initialQuery = getTypedText();                                                               
2066         }                                                                                                
2067         if (appSearchData == null) {                                                                     
2068             appSearchData = new Bundle();                                                                
2069             appSearchData.putString("source", "launcher-search");                                        
2070         }                                                                                                
2071         Rect sourceBounds = new Rect();                                                                  
2072         if (mSearchDropTargetBar != null) {                                                              
2073             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2074         }                                                                                                
2075                                                                                                          
2076         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2077                 appSearchData, sourceBounds);                                                            
2078         if (clearTextImmediately) {                                                                      
2079             clearTypedText();                                                                            
2080         }                                                                                                
2081     }                                                                                                    
2082                                                                                                          
2083     /**                                                                                                  
2084      * Start a text search.                                                                              
2085      *                                                                                                   
2086      * @return {@code true} if the search will start immediately, so any further keypresses              
2087      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2088      * to buffer keypresses.                                                                             
2089      */                                                                                                  
2090     public boolean startSearch(String initialQuery,                                                      
2091             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2092         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2093                 appSearchData, sourceBounds);                                                            
2094         return false;                                                                                    
2095     }                                                                                                    
2096                                                                                                          
2097     /**                                                                                                  
2098      * Starts the global search activity. This code is a copied from SearchManager                       
2099      */                                                                                                  
2100     private void startGlobalSearch(String initialQuery,                                                  
2101             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2102         final SearchManager searchManager =                                                              
2103             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2104         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2105         if (globalSearchActivity == null) {                                                              
2106             Log.w(TAG, "No global search activity found.");                                              
2107             return;                                                                                      
2108         }                                                                                                
2109         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2110         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2111         intent.setComponent(globalSearchActivity);                                                       
2112         // Make sure that we have a Bundle to put source in                                              
2113         if (appSearchData == null) {                                                                     
2114             appSearchData = new Bundle();                                                                
2115         } else {                                                                                         
2116             appSearchData = new Bundle(appSearchData);                                                   
2117         }                                                                                                
2118         // Set source to package name of app that starts global search, if not set already.              
2119         if (!appSearchData.containsKey("source")) {                                                      
2120             appSearchData.putString("source", getPackageName());                                         
2121         }                                                                                                
2122         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2123         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2124             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2125         }                                                                                                
2126         if (selectInitialQuery) {                                                                        
2127             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2128         }                                                                                                
2129         intent.setSourceBounds(sourceBounds);                                                            
2130         try {                                                                                            
2131             startActivity(intent);                                                                       
2132         } catch (ActivityNotFoundException ex) {                                                         
2133             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2134         }                                                                                                
2135     }                                                                                                    
2136                                                                                                          
2137     public boolean isOnCustomContent() {                                                                 
2138         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2139     }                                                                                                    
2140                                                                                                          
2141     @Override                                                                                            
2142     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2143         super.onPrepareOptionsMenu(menu);                                                                
2144         if (!isOnCustomContent()) {                                                                      
2145             // Close any open folders                                                                    
2146             closeFolder();                                                                               
2147             // Stop resizing any widgets                                                                 
2148             mWorkspace.exitWidgetResizeMode();                                                           
2149             if (!mWorkspace.isInOverviewMode()) {                                                        
2150                 // Show the overview mode                                                                
2151                 showOverviewMode(true);                                                                  
2152             } else {                                                                                     
2153                 showWorkspace(true);                                                                     
2154             }                                                                                            
2155         }                                                                                                
2156         return false;                                                                                    
2157     }                                                                                                    
2158                                                                                                          
2159     @Override                                                                                            
2160     public boolean onSearchRequested() {                                                                 
2161         startSearch(null, false, null, true);                                                            
2162         // Use a custom animation for launching search                                                   
2163         return true;                                                                                     
2164     }                                                                                                    
2165                                                                                                          
2166     public boolean isWorkspaceLocked() {                                                                 
2167         return mWorkspaceLoading || mWaitingForResult;                                                   
2168     }                                                                                                    
2169                                                                                                          
2170     public boolean isWorkspaceLoading() {                                                                
2171         return mWorkspaceLoading;                                                                        
2172     }                                                                                                    
2173                                                                                                          
2174     private void setWorkspaceLoading(boolean value) {                                                    
2175         boolean isLocked = isWorkspaceLocked();                                                          
2176         mWorkspaceLoading = value;                                                                       
2177         if (isLocked != isWorkspaceLocked()) {                                                           
2178             onWorkspaceLockedChanged();                                                                  
2179         }                                                                                                
2180     }                                                                                                    
2181                                                                                                          
2182     private void setWaitingForResult(boolean value) {                                                    
2183         boolean isLocked = isWorkspaceLocked();                                                          
2184         mWaitingForResult = value;                                                                       
2185         if (isLocked != isWorkspaceLocked()) {                                                           
2186             onWorkspaceLockedChanged();                                                                  
2187         }                                                                                                
2188     }                                                                                                    
2189                                                                                                          
2190     protected void onWorkspaceLockedChanged() { }                                                        
2191                                                                                                          
2192     private void resetAddInfo() {                                                                        
2193         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2194         mPendingAddInfo.screenId = -1;                                                                   
2195         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2196         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2197         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2198         mPendingAddInfo.dropPos = null;                                                                  
2199     }                                                                                                    
2200                                                                                                          
2201     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2202             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2203         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2204     }                                                                                                    
2205                                                                                                          
2206     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2207             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int          
2208             delay) {                                                                                     
2209         if (appWidgetInfo.configure != null) {                                                           
2210             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2211             mPendingAddWidgetId = appWidgetId;                                                           
2212                                                                                                          
2213             // Launch over to configure widget, if needed                                                
2214             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2215                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2216                                                                                                          
2217         } else {                                                                                         
2218             // Otherwise just add it                                                                     
2219             Runnable onComplete = new Runnable() {                                                       
2220                 @Override                                                                                
2221                 public void run() {                                                                      
2222                     // Exit spring loaded mode if necessary after adding the widget                      
2223                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2224                             null);                                                                       
2225                 }                                                                                        
2226             };                                                                                           
2227             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2228                     appWidgetInfo);                                                                      
2229             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2230         }                                                                                                
2231     }                                                                                                    
2232                                                                                                          
2233     protected void moveToCustomContentScreen(boolean animate) {                                          
2234         // Close any folders that may be open.                                                           
2235         closeFolder();                                                                                   
2236         mWorkspace.moveToCustomContentScreen(animate);                                                   
2237     }                                                                                                    
2238     /**                                                                                                  
2239      * Process a shortcut drop.                                                                          
2240      *                                                                                                   
2241      * @param componentName The name of the component                                                    
2242      * @param screenId The ID of the screen where it should be added                                     
2243      * @param cell The cell it should be added to, optional                                              
2244      * @param position The location on the screen where it was dropped, optional                         
2245      */                                                                                                  
2246     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2247             int[] cell, int[] loc) {                                                                     
2248         resetAddInfo();                                                                                  
2249         mPendingAddInfo.container = container;                                                           
2250         mPendingAddInfo.screenId = screenId;                                                             
2251         mPendingAddInfo.dropPos = loc;                                                                   
2252                                                                                                          
2253         if (cell != null) {                                                                              
2254             mPendingAddInfo.cellX = cell[0];                                                             
2255             mPendingAddInfo.cellY = cell[1];                                                             
2256         }                                                                                                
2257                                                                                                          
2258         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2259         createShortcutIntent.setComponent(componentName);                                                
2260         processShortcut(createShortcutIntent);                                                           
2261     }                                                                                                    
2262                                                                                                          
2263     /**                                                                                                  
2264      * Process a widget drop.                                                                            
2265      *                                                                                                   
2266      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2267      * @param screenId The ID of the screen where it should be added                                     
2268      * @param cell The cell it should be added to, optional                                              
2269      * @param position The location on the screen where it was dropped, optional                         
2270      */                                                                                                  
2271     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                  
2272             int[] cell, int[] span, int[] loc) {                                                         
2273         resetAddInfo();                                                                                  
2274         mPendingAddInfo.container = info.container = container;                                          
2275         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2276         mPendingAddInfo.dropPos = loc;                                                                   
2277         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2278         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2279                                                                                                          
2280         if (cell != null) {                                                                              
2281             mPendingAddInfo.cellX = cell[0];                                                             
2282             mPendingAddInfo.cellY = cell[1];                                                             
2283         }                                                                                                
2284         if (span != null) {                                                                              
2285             mPendingAddInfo.spanX = span[0];                                                             
2286             mPendingAddInfo.spanY = span[1];                                                             
2287         }                                                                                                
2288                                                                                                          
2289         AppWidgetHostView hostView = info.boundWidget;                                                   
2290         int appWidgetId;                                                                                 
2291         if (hostView != null) {                                                                          
2292             appWidgetId = hostView.getAppWidgetId();                                                     
2293             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2294         } else {                                                                                         
2295             // In this case, we either need to start an activity to get permission to bind               
2296             // the widget, or we need to start an activity to configure the widget, or both.             
2297             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2298             Bundle options = info.bindOptions;                                                           
2299                                                                                                          
2300             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2301                     appWidgetId, info.info, options);                                                    
2302             if (success) {                                                                               
2303                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2304             } else {                                                                                     
2305                 mPendingAddWidgetInfo = info.info;                                                       
2306                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2307                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2308                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2309                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2310                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2311                 // TODO: we need to make sure that this accounts for the options bundle.                 
2312                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2313                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2314             }                                                                                            
2315         }                                                                                                
2316     }                                                                                                    
2317                                                                                                          
2318     void processShortcut(Intent intent) {                                                                
2319         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2320     }                                                                                                    
2321                                                                                                          
2322     void processWallpaper(Intent intent) {                                                               
2323         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2324     }                                                                                                    
2325                                                                                                          
2326     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2327             int cellY) {                                                                                 
2328         final FolderInfo folderInfo = new FolderInfo();                                                  
2329         folderInfo.title = getText(R.string.folder_name);                                                
2330                                                                                                          
2331         // Update the model                                                                              
2332         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2333                 false);                                                                                  
2334         sFolders.put(folderInfo.id, folderInfo);                                                         
2335                                                                                                          
2336         // Create the view                                                                               
2337         FolderIcon newFolder =                                                                           
2338             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2339         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2340                 isWorkspaceLocked());                                                                    
2341         // Force measure the new folder icon                                                             
2342         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2343         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2344         return newFolder;                                                                                
2345     }                                                                                                    
2346                                                                                                          
2347     void removeFolder(FolderInfo folder) {                                                               
2348         sFolders.remove(folder.id);                                                                      
2349     }                                                                                                    
2350                                                                                                          
2351     protected ComponentName getWallpaperPickerComponent() {                                              
2352         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2353     }                                                                                                    
2354                                                                                                          
2355     /**                                                                                                  
2356      * Registers various content observers. The current implementation registers                         
2357      * only a favorites observer to keep track of the favorites applications.                            
2358      */                                                                                                  
2359     private void registerContentObservers() {                                                            
2360         ContentResolver resolver = getContentResolver();                                                 
2361         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2362                 true, mWidgetObserver);                                                                  
2363     }                                                                                                    
2364                                                                                                          
2365     @Override                                                                                            
2366     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2367         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2368             switch (event.getKeyCode()) {                                                                
2369                 case KeyEvent.KEYCODE_HOME:                                                              
2370                     return true;                                                                         
2371                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2372                     if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                        
2373                         dumpState();                                                                     
2374                         return true;                                                                     
2375                     }                                                                                    
2376                     break;                                                                               
2377             }                                                                                            
2378         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2379             switch (event.getKeyCode()) {                                                                
2380                 case KeyEvent.KEYCODE_HOME:                                                              
2381                     return true;                                                                         
2382             }                                                                                            
2383         }                                                                                                
2384                                                                                                          
2385         return super.dispatchKeyEvent(event);                                                            
2386     }                                                                                                    
2387                                                                                                          
2388     @Override                                                                                            
2389     public void onBackPressed() {                                                                        
2390         if (isAllAppsVisible()) {                                                                        
2391             if (mAppsCustomizeContent.getContentType() ==                                                
2392                     AppsCustomizePagedView.ContentType.Applications) {                                   
2393                 showWorkspace(true);                                                                     
2394             } else {                                                                                     
2395                 showOverviewMode(true);                                                                  
2396             }                                                                                            
2397         } else if (mWorkspace.isInOverviewMode()) {                                                      
2398             mWorkspace.exitOverviewMode(true);                                                           
2399         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2400             Folder openFolder = mWorkspace.getOpenFolder();                                              
2401             if (openFolder.isEditingName()) {                                                            
2402                 openFolder.dismissEditingName();                                                         
2403             } else {                                                                                     
2404                 closeFolder();                                                                           
2405             }                                                                                            
2406         } else {                                                                                         
2407             mWorkspace.exitWidgetResizeMode();                                                           
2408                                                                                                          
2409             // Back button is a no-op here, but give at least some feedback for the button press         
2410             mWorkspace.showOutlinesTemporarily();                                                        
2411         }                                                                                                
2412     }                                                                                                    
2413                                                                                                          
2414     /**                                                                                                  
2415      * Re-listen when widgets are reset.                                                                 
2416      */                                                                                                  
2417     private void onAppWidgetReset() {                                                                    
2418         if (mAppWidgetHost != null) {                                                                    
2419             mAppWidgetHost.startListening();                                                             
2420         }                                                                                                
2421     }                                                                                                    
2422                                                                                                          
2423     /**                                                                                                  
2424      * Launches the intent referred by the clicked shortcut.                                             
2425      *                                                                                                   
2426      * @param v The view representing the clicked shortcut.                                              
2427      */                                                                                                  
2428     public void onClick(View v) {                                                                        
2429         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2430         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2431         if (v.getWindowToken() == null) {                                                                
2432             return;                                                                                      
2433         }                                                                                                
2434                                                                                                          
2435         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2436             return;                                                                                      
2437         }                                                                                                
2438                                                                                                          
2439         if (v instanceof Workspace) {                                                                    
2440             if (mWorkspace.isInOverviewMode()) {                                                         
2441                 mWorkspace.exitOverviewMode(true);                                                       
2442             }                                                                                            
2443             return;                                                                                      
2444         }                                                                                                
2445                                                                                                          
2446         if (v instanceof CellLayout) {                                                                   
2447             if (mWorkspace.isInOverviewMode()) {                                                         
2448                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2449             }                                                                                            
2450         }                                                                                                
2451                                                                                                          
2452         Object tag = v.getTag();                                                                         
2453         if (tag instanceof ShortcutInfo) {                                                               
2454             onClickAppShortcut(v);                                                                       
2455         } else if (tag instanceof FolderInfo) {                                                          
2456             if (v instanceof FolderIcon) {                                                               
2457                 onClickFolderIcon(v);                                                                    
2458             }                                                                                            
2459         } else if (v == mAllAppsButton) {                                                                
2460             onClickAllAppsButton(v);                                                                     
2461         } else if (tag instanceof AppInfo) {                                                             
2462             startAppShortcutOrInfoActivity(v);                                                           
2463         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2464             if (v instanceof PendingAppWidgetHostView) {                                                 
2465                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2466             }                                                                                            
2467         }                                                                                                
2468     }                                                                                                    
2469                                                                                                          
2470     public void onClickPagedViewIcon(View v) {                                                           
2471         startAppShortcutOrInfoActivity(v);                                                               
2472     }                                                                                                    
2473                                                                                                          
2474     public boolean onTouch(View v, MotionEvent event) {                                                  
2475         return false;                                                                                    
2476     }                                                                                                    
2477                                                                                                          
2478     /**                                                                                                  
2479      * Event handler for the app widget view which has not fully restored.                               
2480      */                                                                                                  
2481     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2482         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2483         if (v.isReadyForClickSetup()) {                                                                  
2484             int widgetId = info.appWidgetId;                                                             
2485             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2486             if (appWidgetInfo != null) {                                                                 
2487                 mPendingAddWidgetInfo = appWidgetInfo;                                                   
2488                 mPendingAddInfo.copyFrom(info);                                                          
2489                 mPendingAddWidgetId = widgetId;                                                          
2490                                                                                                          
2491                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2492                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2493             }                                                                                            
2494         } else if (info.installProgress < 0) {                                                           
2495             // The install has not been queued                                                           
2496             final String packageName = info.providerName.getPackageName();                               
2497             showBrokenAppInstallDialog(packageName,                                                      
2498                 new DialogInterface.OnClickListener() {                                                  
2499                     public void onClick(DialogInterface dialog, int id) {                                
2500                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2501                     }                                                                                    
2502                 });                                                                                      
2503         } else {                                                                                         
2504             // Download has started.                                                                     
2505             final String packageName = info.providerName.getPackageName();                               
2506             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2507         }                                                                                                
2508     }                                                                                                    
2509                                                                                                          
2510     /**                                                                                                  
2511      * Event handler for the search button                                                               
2512      *                                                                                                   
2513      * @param v The view that was clicked.                                                               
2514      */                                                                                                  
2515     public void onClickSearchButton(View v) {                                                            
2516         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2517                                                                                                          
2518         onSearchRequested();                                                                             
2519     }                                                                                                    
2520                                                                                                          
2521     /**                                                                                                  
2522      * Event handler for the voice button                                                                
2523      *                                                                                                   
2524      * @param v The view that was clicked.                                                               
2525      */                                                                                                  
2526     public void onClickVoiceButton(View v) {                                                             
2527         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2528                                                                                                          
2529         startVoice();                                                                                    
2530     }                                                                                                    
2531                                                                                                          
2532     public void startVoice() {                                                                           
2533         try {                                                                                            
2534             final SearchManager searchManager =                                                          
2535                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);                            
2536             ComponentName activityName = searchManager.getGlobalSearchActivity();                        
2537             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2538             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2539             if (activityName != null) {                                                                  
2540                 intent.setPackage(activityName.getPackageName());                                        
2541             }                                                                                            
2542             startActivity(null, intent, "onClickVoiceButton");                                           
2543         } catch (ActivityNotFoundException e) {                                                          
2544             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2545             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2546             startActivitySafely(null, intent, "onClickVoiceButton");                                     
2547         }                                                                                                
2548     }                                                                                                    
2549                                                                                                          
2550     /**                                                                                                  
2551      * Event handler for the "grid" button that appears on the home screen, which                        
2552      * enters all apps mode.                                                                             
2553      *                                                                                                   
2554      * @param v The view that was clicked.                                                               
2555      */                                                                                                  
2556     protected void onClickAllAppsButton(View v) {                                                        
2557         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2558         if (isAllAppsVisible()) {                                                                        
2559             showWorkspace(true);                                                                         
2560         } else {                                                                                         
2561             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                   
2562         }                                                                                                
2563     }                                                                                                    
2564                                                                                                          
2565     private void showBrokenAppInstallDialog(final String packageName,                                    
2566             DialogInterface.OnClickListener onSearchClickListener) {                                     
2567         new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))      
2568             .setTitle(R.string.abandoned_promises_title)                                                 
2569             .setMessage(R.string.abandoned_promise_explanation)                                          
2570             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2571             .setNeutralButton(R.string.abandoned_clean_this,                                             
2572                 new DialogInterface.OnClickListener() {                                                  
2573                     public void onClick(DialogInterface dialog, int id) {                                
2574                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2575                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2576                     }                                                                                    
2577                 })                                                                                       
2578             .create().show();                                                                            
2579         return;                                                                                          
2580     }                                                                                                    
2581                                                                                                          
2582     /**                                                                                                  
2583      * Event handler for an app shortcut click.                                                          
2584      *                                                                                                   
2585      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2586      */                                                                                                  
2587     protected void onClickAppShortcut(final View v) {                                                    
2588         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2589         Object tag = v.getTag();                                                                         
2590         if (!(tag instanceof ShortcutInfo)) {                                                            
2591             throw new IllegalArgumentException("Input must be a Shortcut");                              
2592         }                                                                                                
2593                                                                                                          
2594         // Open shortcut                                                                                 
2595         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2596         final Intent intent = shortcut.intent;                                                           
2597                                                                                                          
2598         // Check for special shortcuts                                                                   
2599         if (intent.getComponent() != null) {                                                             
2600             final String shortcutClass = intent.getComponent().getClassName();                           
2601                                                                                                          
2602             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2603                 MemoryDumpActivity.startDump(this);                                                      
2604                 return;                                                                                  
2605             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2606                 toggleShowWeightWatcher();                                                               
2607                 return;                                                                                  
2608             }                                                                                            
2609         }                                                                                                
2610                                                                                                          
2611         // Check for abandoned promise                                                                   
2612         if ((v instanceof BubbleTextView)                                                                
2613                 && shortcut.isPromise()                                                                  
2614                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2615             showBrokenAppInstallDialog(                                                                  
2616                     shortcut.getTargetComponent().getPackageName(),                                      
2617                     new DialogInterface.OnClickListener() {                                              
2618                         public void onClick(DialogInterface dialog, int id) {                            
2619                             startAppShortcutOrInfoActivity(v);                                           
2620                         }                                                                                
2621                     });                                                                                  
2622             return;                                                                                      
2623         }                                                                                                
2624                                                                                                          
2625         // Start activities                                                                              
2626         startAppShortcutOrInfoActivity(v);                                                               
2627     }                                                                                                    
2628                                                                                                          
2629     private void startAppShortcutOrInfoActivity(View v) {                                                
2630         Object tag = v.getTag();                                                                         
2631         final ShortcutInfo shortcut;                                                                     
2632         final Intent intent;                                                                             
2633         if (tag instanceof ShortcutInfo) {                                                               
2634             shortcut = (ShortcutInfo) tag;                                                               
2635             intent = shortcut.intent;                                                                    
2636             int[] pos = new int[2];                                                                      
2637             v.getLocationOnScreen(pos);                                                                  
2638             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2639                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2640                                                                                                          
2641         } else if (tag instanceof AppInfo) {                                                             
2642             shortcut = null;                                                                             
2643             intent = ((AppInfo) tag).intent;                                                             
2644         } else {                                                                                         
2645             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2646         }                                                                                                
2647                                                                                                          
2648         boolean success = startActivitySafely(v, intent, tag);                                           
2649         mStats.recordLaunch(intent, shortcut);                                                           
2650                                                                                                          
2651         if (success && v instanceof BubbleTextView) {                                                    
2652             mWaitingForResume = (BubbleTextView) v;                                                      
2653             mWaitingForResume.setStayPressed(true);                                                      
2654         }                                                                                                
2655     }                                                                                                    
2656                                                                                                          
2657     /**                                                                                                  
2658      * Event handler for a folder icon click.                                                            
2659      *                                                                                                   
2660      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2661      */                                                                                                  
2662     protected void onClickFolderIcon(View v) {                                                           
2663         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2664         if (!(v instanceof FolderIcon)){                                                                 
2665             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2666         }                                                                                                
2667                                                                                                          
2668         FolderIcon folderIcon = (FolderIcon) v;                                                          
2669         final FolderInfo info = folderIcon.getFolderInfo();                                              
2670         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2671                                                                                                          
2672         // If the folder info reports that the associated folder is open, then verify that               
2673         // it is actually opened. There have been a few instances where this gets out of sync.           
2674         if (info.opened && openFolder == null) {                                                         
2675             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2676                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2677             info.opened = false;                                                                         
2678         }                                                                                                
2679                                                                                                          
2680         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2681             // Close any open folder                                                                     
2682             closeFolder();                                                                               
2683             // Open the requested folder                                                                 
2684             openFolder(folderIcon);                                                                      
2685         } else {                                                                                         
2686             // Find the open folder...                                                                   
2687             int folderScreen;                                                                            
2688             if (openFolder != null) {                                                                    
2689                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2690                 // .. and close it                                                                       
2691                 closeFolder(openFolder);                                                                 
2692                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2693                     // Close any folder open on the current screen                                       
2694                     closeFolder();                                                                       
2695                     // Pull the folder onto this screen                                                  
2696                     openFolder(folderIcon);                                                              
2697                 }                                                                                        
2698             }                                                                                            
2699         }                                                                                                
2700     }                                                                                                    
2701                                                                                                          
2702     /**                                                                                                  
2703      * Event handler for the (Add) Widgets button that appears after a long press                        
2704      * on the home screen.                                                                               
2705      */                                                                                                  
2706     protected void onClickAddWidgetButton(View view) {                                                   
2707         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2708         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                             
2709     }                                                                                                    
2710                                                                                                          
2711     /**                                                                                                  
2712      * Event handler for the wallpaper picker button that appears after a long press                     
2713      * on the home screen.                                                                               
2714      */                                                                                                  
2715     protected void onClickWallpaperPicker(View v) {                                                      
2716         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2717         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2718         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2719         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2720     }                                                                                                    
2721                                                                                                          
2722     /**                                                                                                  
2723      * Event handler for a click on the settings button that appears after a long press                  
2724      * on the home screen.                                                                               
2725      */                                                                                                  
2726     protected void onClickSettingsButton(View v) {                                                       
2727         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2728     }                                                                                                    
2729                                                                                                          
2730     public void onTouchDownAllAppsButton(View v) {                                                       
2731         // Provide the same haptic feedback that the system offers for virtual keys.                     
2732         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2733     }                                                                                                    
2734                                                                                                          
2735     public void performHapticFeedbackOnTouchDown(View v) {                                               
2736         // Provide the same haptic feedback that the system offers for virtual keys.                     
2737         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2738     }                                                                                                    
2739                                                                                                          
2740     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2741         if (mHapticFeedbackTouchListener == null) {                                                      
2742             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2743                 @Override                                                                                
2744                 public boolean onTouch(View v, MotionEvent event) {                                      
2745                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2746                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2747                     }                                                                                    
2748                     return false;                                                                        
2749                 }                                                                                        
2750             };                                                                                           
2751         }                                                                                                
2752         return mHapticFeedbackTouchListener;                                                             
2753     }                                                                                                    
2754                                                                                                          
2755     public void onDragStarted(View view) {}                                                              
2756                                                                                                          
2757     /**                                                                                                  
2758      * Called when the user stops interacting with the launcher.                                         
2759      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2760      */                                                                                                  
2761     protected void onInteractionEnd() {}                                                                 
2762                                                                                                          
2763     /**                                                                                                  
2764      * Called when the user starts interacting with the launcher.                                        
2765      * The possible interactions are:                                                                    
2766      *  - open all apps                                                                                  
2767      *  - reorder an app shortcut, or a widget                                                           
2768      *  - open the overview mode.                                                                        
2769      * This is a good time to stop doing things that only make sense                                     
2770      * when the user is on the homescreen and not doing housekeeping.                                    
2771      */                                                                                                  
2772     protected void onInteractionBegin() {}                                                               
2773                                                                                                          
2774     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2775         String packageName = componentName.getPackageName();                                             
2776         try {                                                                                            
2777             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2778             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2779             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2780         } catch (SecurityException e) {                                                                  
2781             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2782             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2783         } catch (ActivityNotFoundException e) {                                                          
2784             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2785             Log.e(TAG, "Unable to launch settings");                                                     
2786         }                                                                                                
2787     }                                                                                                    
2788                                                                                                          
2789     // returns true if the activity was started                                                          
2790     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2791             UserHandleCompat user) {                                                                     
2792         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2793             // System applications cannot be installed. For now, show a toast explaining that.           
2794             // We may give them the option of disabling apps this way.                                   
2795             int messageId = R.string.uninstall_system_app_text;                                          
2796             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2797             return false;                                                                                
2798         } else {                                                                                         
2799             String packageName = componentName.getPackageName();                                         
2800             String className = componentName.getClassName();                                             
2801             Intent intent = new Intent(                                                                  
2802                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2803             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2804                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2805             if (user != null) {                                                                          
2806                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2807             }                                                                                            
2808             startActivity(intent);                                                                       
2809             return true;                                                                                 
2810         }                                                                                                
2811     }                                                                                                    
2812                                                                                                          
2813     boolean startActivity(View v, Intent intent, Object tag) {                                           
2814         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2815         try {                                                                                            
2816             // Only launch using the new animation if the shortcut has not opted out (this is a          
2817             // private contract between launcher and may be ignored in the future).                      
2818             boolean useLaunchAnimation = (v != null) &&                                                  
2819                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2820             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2821             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2822                                                                                                          
2823             UserHandleCompat user = null;                                                                
2824             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2825                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2826                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2827             }                                                                                            
2828                                                                                                          
2829             Bundle optsBundle = null;                                                                    
2830             if (useLaunchAnimation) {                                                                    
2831                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2832                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2833                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2834                 optsBundle = opts.toBundle();                                                            
2835             }                                                                                            
2836                                                                                                          
2837             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2838                 // Could be launching some bookkeeping activity                                          
2839                 startActivity(intent, optsBundle);                                                       
2840             } else {                                                                                     
2841                 // TODO Component can be null when shortcuts are supported for secondary user            
2842                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2843                         intent.getSourceBounds(), optsBundle);                                           
2844             }                                                                                            
2845             return true;                                                                                 
2846         } catch (SecurityException e) {                                                                  
2847             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2848             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2849                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2850                     "or use the exported attribute for this activity. "                                  
2851                     + "tag="+ tag + " intent=" + intent, e);                                             
2852         }                                                                                                
2853         return false;                                                                                    
2854     }                                                                                                    
2855                                                                                                          
2856     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2857         boolean success = false;                                                                         
2858         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2859             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2860             return false;                                                                                
2861         }                                                                                                
2862         try {                                                                                            
2863             success = startActivity(v, intent, tag);                                                     
2864         } catch (ActivityNotFoundException e) {                                                          
2865             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2866             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2867         }                                                                                                
2868         return success;                                                                                  
2869     }                                                                                                    
2870                                                                                                          
2871     /**                                                                                                  
2872      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2873      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2874      */                                                                                                  
2875     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2876         final int width = fi.getMeasuredWidth();                                                         
2877         final int height = fi.getMeasuredHeight();                                                       
2878                                                                                                          
2879         // Lazy load ImageView, Bitmap and Canvas                                                        
2880         if (mFolderIconImageView == null) {                                                              
2881             mFolderIconImageView = new ImageView(this);                                                  
2882         }                                                                                                
2883         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2884                 mFolderIconBitmap.getHeight() != height) {                                               
2885             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2886             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2887         }                                                                                                
2888                                                                                                          
2889         DragLayer.LayoutParams lp;                                                                       
2890         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2891             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2892         } else {                                                                                         
2893             lp = new DragLayer.LayoutParams(width, height);                                              
2894         }                                                                                                
2895                                                                                                          
2896         // The layout from which the folder is being opened may be scaled, adjust the starting           
2897         // view size by this scale factor.                                                               
2898         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2899         lp.customPosition = true;                                                                        
2900         lp.x = mRectForFolderAnimation.left;                                                             
2901         lp.y = mRectForFolderAnimation.top;                                                              
2902         lp.width = (int) (scale * width);                                                                
2903         lp.height = (int) (scale * height);                                                              
2904                                                                                                          
2905         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
2906         fi.draw(mFolderIconCanvas);                                                                      
2907         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
2908         if (fi.getFolder() != null) {                                                                    
2909             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
2910             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
2911         }                                                                                                
2912         // Just in case this image view is still in the drag layer from a previous animation,            
2913         // we remove it and re-add it.                                                                   
2914         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
2915             mDragLayer.removeView(mFolderIconImageView);                                                 
2916         }                                                                                                
2917         mDragLayer.addView(mFolderIconImageView, lp);                                                    
2918         if (fi.getFolder() != null) {                                                                    
2919             fi.getFolder().bringToFront();                                                               
2920         }                                                                                                
2921     }                                                                                                    
2922                                                                                                          
2923     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
2924         if (fi == null) return;                                                                          
2925         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
2926         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
2927         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
2928                                                                                                          
2929         FolderInfo info = (FolderInfo) fi.getTag();                                                      
2930         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
2931             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
2932             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
2933             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
2934         }                                                                                                
2935                                                                                                          
2936         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
2937         copyFolderIconToImage(fi);                                                                       
2938         fi.setVisibility(View.INVISIBLE);                                                                
2939                                                                                                          
2940         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
2941                 scaleX, scaleY);                                                                         
2942         if (Utilities.isLmpOrAbove()) {                                                                  
2943             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
2944         }                                                                                                
2945         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2946         oa.start();                                                                                      
2947     }                                                                                                    
2948                                                                                                          
2949     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
2950         if (fi == null) return;                                                                          
2951         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
2952         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
2953         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
2954                                                                                                          
2955         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
2956                                                                                                          
2957         // We remove and re-draw the FolderIcon in-case it has changed                                   
2958         mDragLayer.removeView(mFolderIconImageView);                                                     
2959         copyFolderIconToImage(fi);                                                                       
2960         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
2961                 scaleX, scaleY);                                                                         
2962         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2963         oa.addListener(new AnimatorListenerAdapter() {                                                   
2964             @Override                                                                                    
2965             public void onAnimationEnd(Animator animation) {                                             
2966                 if (cl != null) {                                                                        
2967                     cl.clearFolderLeaveBehind();                                                         
2968                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
2969                     mDragLayer.removeView(mFolderIconImageView);                                         
2970                     fi.setVisibility(View.VISIBLE);                                                      
2971                 }                                                                                        
2972             }                                                                                            
2973         });                                                                                              
2974         oa.start();                                                                                      
2975     }                                                                                                    
2976                                                                                                          
2977     /**                                                                                                  
2978      * Opens the user folder described by the specified tag. The opening of the folder                   
2979      * is animated relative to the specified View. If the View is null, no animation                     
2980      * is played.                                                                                        
2981      *                                                                                                   
2982      * @param folderInfo The FolderInfo describing the folder to open.                                   
2983      */                                                                                                  
2984     public void openFolder(FolderIcon folderIcon) {                                                      
2985         Folder folder = folderIcon.getFolder();                                                          
2986         FolderInfo info = folder.mInfo;                                                                  
2987                                                                                                          
2988         info.opened = true;                                                                              
2989                                                                                                          
2990         // Just verify that the folder hasn't already been added to the DragLayer.                       
2991         // There was a one-off crash where the folder had a parent already.                              
2992         if (folder.getParent() == null) {                                                                
2993             mDragLayer.addView(folder);                                                                  
2994             mDragController.addDropTarget((DropTarget) folder);                                          
2995         } else {                                                                                         
2996             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
2997                     folder.getParent() + ").");                                                          
2998         }                                                                                                
2999         folder.animateOpen();                                                                            
3000         growAndFadeOutFolderIcon(folderIcon);                                                            
3001                                                                                                          
3002         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3003         // the workspace items                                                                           
3004         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3005         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3006     }                                                                                                    
3007                                                                                                          
3008     public void closeFolder() {                                                                          
3009         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3010         if (folder != null) {                                                                            
3011             if (folder.isEditingName()) {                                                                
3012                 folder.dismissEditingName();                                                             
3013             }                                                                                            
3014             closeFolder(folder);                                                                         
3015         }                                                                                                
3016     }                                                                                                    
3017                                                                                                          
3018     void closeFolder(Folder folder) {                                                                    
3019         folder.getInfo().opened = false;                                                                 
3020                                                                                                          
3021         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3022         if (parent != null) {                                                                            
3023             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3024             shrinkAndFadeInFolderIcon(fi);                                                               
3025         }                                                                                                
3026         folder.animateClosed();                                                                          
3027                                                                                                          
3028         // Notify the accessibility manager that this folder "window" has disappeard and no              
3029         // longer occludeds the workspace items                                                          
3030         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3031     }                                                                                                    
3032                                                                                                          
3033     public boolean onLongClick(View v) {                                                                 
3034         if (!isDraggingEnabled()) return false;                                                          
3035         if (isWorkspaceLocked()) return false;                                                           
3036         if (mState != State.WORKSPACE) return false;                                                     
3037                                                                                                          
3038         if (v instanceof Workspace) {                                                                    
3039             if (!mWorkspace.isInOverviewMode()) {                                                        
3040                 if (mWorkspace.enterOverviewMode()) {                                                    
3041                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3042                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3043                     return true;                                                                         
3044                 } else {                                                                                 
3045                     return false;                                                                        
3046                 }                                                                                        
3047             } else {                                                                                     
3048                 return false;                                                                            
3049             }                                                                                            
3050         }                                                                                                
3051                                                                                                          
3052         CellLayout.CellInfo longClickCellInfo = null;                                                    
3053         View itemUnderLongClick = null;                                                                  
3054         if (v.getTag() instanceof ItemInfo) {                                                            
3055             ItemInfo info = (ItemInfo) v.getTag();                                                       
3056             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3057             itemUnderLongClick = longClickCellInfo.cell;                                                 
3058             resetAddInfo();                                                                              
3059         }                                                                                                
3060                                                                                                          
3061         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3062         // on hotseat items.                                                                             
3063         final boolean inHotseat = isHotseatLayout(v);                                                    
3064         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3065         if (allowLongPress && !mDragController.isDragging()) {                                           
3066             if (itemUnderLongClick == null) {                                                            
3067                 // User long pressed on empty space                                                      
3068                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3069                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3070                 if (mWorkspace.isInOverviewMode()) {                                                     
3071                     mWorkspace.startReordering(v);                                                       
3072                 } else {                                                                                 
3073                     mWorkspace.enterOverviewMode();                                                      
3074                 }                                                                                        
3075             } else {                                                                                     
3076                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3077                         mHotseat.getOrderInHotseat(                                                      
3078                                 longClickCellInfo.cellX,                                                 
3079                                 longClickCellInfo.cellY));                                               
3080                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3081                     // User long pressed on an item                                                      
3082                     mWorkspace.startDrag(longClickCellInfo);                                             
3083                 }                                                                                        
3084             }                                                                                            
3085         }                                                                                                
3086         return true;                                                                                     
3087     }                                                                                                    
3088                                                                                                          
3089     boolean isHotseatLayout(View layout) {                                                               
3090         return mHotseat != null && layout != null &&                                                     
3091                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3092     }                                                                                                    
3093                                                                                                          
3094     /**                                                                                                  
3095      * Returns the CellLayout of the specified container at the specified screen.                        
3096      */                                                                                                  
3097     CellLayout getCellLayout(long container, long screenId) {                                            
3098         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3099             if (mHotseat != null) {                                                                      
3100                 return mHotseat.getLayout();                                                             
3101             } else {                                                                                     
3102                 return null;                                                                             
3103             }                                                                                            
3104         } else {                                                                                         
3105             return (CellLayout) mWorkspace.getScreenWithId(screenId);                                    
3106         }                                                                                                
3107     }                                                                                                    
3108                                                                                                          
3109     public boolean isAllAppsVisible() {                                                                  
3110         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);             
3111     }                                                                                                    
3112                                                                                                          
3113     private void setWorkspaceBackground(boolean workspace) {                                             
3114         mLauncherView.setBackground(workspace ?                                                          
3115                 mWorkspaceBackgroundDrawable : null);                                                    
3116     }                                                                                                    
3117                                                                                                          
3118     protected void changeWallpaperVisiblity(boolean visible) {                                           
3119         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3120         int curflags = getWindow().getAttributes().flags                                                 
3121                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3122         if (wpflags != curflags) {                                                                       
3123             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3124         }                                                                                                
3125         setWorkspaceBackground(visible);                                                                 
3126     }                                                                                                    
3127                                                                                                          
3128     private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {    
3129         if (v instanceof LauncherTransitionable) {                                                       
3130             ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);       
3131         }                                                                                                
3132     }                                                                                                    
3133                                                                                                          
3134     private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {      
3135         if (v instanceof LauncherTransitionable) {                                                       
3136             ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);         
3137         }                                                                                                
3138                                                                                                          
3139         // Update the workspace transition step as well                                                  
3140         dispatchOnLauncherTransitionStep(v, 0f);                                                         
3141     }                                                                                                    
3142                                                                                                          
3143     private void dispatchOnLauncherTransitionStep(View v, float t) {                                     
3144         if (v instanceof LauncherTransitionable) {                                                       
3145             ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                              
3146         }                                                                                                
3147     }                                                                                                    
3148                                                                                                          
3149     private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {        
3150         if (v instanceof LauncherTransitionable) {                                                       
3151             ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);           
3152         }                                                                                                
3153                                                                                                          
3154         // Update the workspace transition step as well                                                  
3155         dispatchOnLauncherTransitionStep(v, 1f);                                                         
3156     }                                                                                                    
3157                                                                                                          
3158     /**                                                                                                  
3159      * Things to test when changing the following seven functions.                                       
3160      *   - Home from workspace                                                                           
3161      *          - from center screen                                                                     
3162      *          - from other screens                                                                     
3163      *   - Home from all apps                                                                            
3164      *          - from center screen                                                                     
3165      *          - from other screens                                                                     
3166      *   - Back from all apps                                                                            
3167      *          - from center screen                                                                     
3168      *          - from other screens                                                                     
3169      *   - Launch app from workspace and quit                                                            
3170      *          - with back                                                                              
3171      *          - with home                                                                              
3172      *   - Launch app from all apps and quit                                                             
3173      *          - with back                                                                              
3174      *          - with home                                                                              
3175      *   - Go to a screen that's not the default, then all                                               
3176      *     apps, and launch and app, and go back                                                         
3177      *          - with back                                                                              
3178      *          -with home                                                                               
3179      *   - On workspace, long press power and go back                                                    
3180      *          - with back                                                                              
3181      *          - with home                                                                              
3182      *   - On all apps, long press power and go back                                                     
3183      *          - with back                                                                              
3184      *          - with home                                                                              
3185      *   - On workspace, power off                                                                       
3186      *   - On all apps, power off                                                                        
3187      *   - Launch an app and turn off the screen while in that app                                       
3188      *          - Go back with home key                                                                  
3189      *          - Go back with back key  TODO: make this not go to workspace                             
3190      *          - From all apps                                                                          
3191      *          - From workspace                                                                         
3192      *   - Enter and exit car mode (becuase it causes an extra configuration changed)                    
3193      *          - From all apps                                                                          
3194      *          - From the center workspace                                                              
3195      *          - From another workspace                                                                 
3196      */                                                                                                  
3197                                                                                                          
3198     /**                                                                                                  
3199      * Zoom the camera out from the workspace to reveal 'toView'.                                        
3200      * Assumes that the view to show is anchored at either the very top or very bottom                   
3201      * of the screen.                                                                                    
3202      */                                                                                                  
3203     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {           
3204         AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();         
3205         showAppsCustomizeHelper(animated, springLoaded, contentType);                                    
3206     }                                                                                                    
3207                                                                                                          
3208     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,             
3209                                          final AppsCustomizePagedView.ContentType contentType) {         
3210         if (mStateAnimation != null) {                                                                   
3211             mStateAnimation.setDuration(0);                                                              
3212             mStateAnimation.cancel();                                                                    
3213             mStateAnimation = null;                                                                      
3214         }                                                                                                
3215                                                                                                          
3216         boolean material = Utilities.isLmpOrAbove();                                                     
3217                                                                                                          
3218         final Resources res = getResources();                                                            
3219                                                                                                          
3220         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                   
3221         final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);               
3222         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);             
3223         final int itemsAlphaStagger =                                                                    
3224                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3225                                                                                                          
3226         final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);       
3227         final View fromView = mWorkspace;                                                                
3228         final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                       
3229                                                                                                          
3230         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3231                                                                                                          
3232         Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?     
3233                 Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                         
3234         Animator workspaceAnim =                                                                         
3235                 mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                
3236         if (!LauncherAppState.isDisableAllApps()                                                         
3237                 || contentType == AppsCustomizePagedView.ContentType.Widgets) {                          
3238             // Set the content type for the all apps/widgets space                                       
3239             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                  
3240         }                                                                                                
3241                                                                                                          
3242         // If for some reason our views aren't initialized, don't animate                                
3243         boolean initialized = getAllAppsButton() != null;                                                
3244                                                                                                          
3245         if (animated && initialized) {                                                                   
3246             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3247             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3248                     toView.findViewById(R.id.apps_customize_pane_content);                               
3249                                                                                                          
3250             final View page = content.getPageAt(content.getCurrentPage());                               
3251             final View revealView = toView.findViewById(R.id.fake_page);                                 
3252                                                                                                          
3253             final float initialPanelAlpha = 1f;                                                          
3254                                                                                                          
3255             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;      
3256             if (isWidgetTray) {                                                                          
3257                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                
3258             } else {                                                                                     
3259                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                     
3260             }                                                                                            
3261                                                                                                          
3262             // Hide the real page background, and swap in the fake one                                   
3263             content.setPageBackgroundsVisible(false);                                                    
3264             revealView.setVisibility(View.VISIBLE);                                                      
3265             // We need to hide this view as the animation start will be posted.                          
3266             revealView.setAlpha(0);                                                                      
3267                                                                                                          
3268             int width = revealView.getMeasuredWidth();                                                   
3269             int height = revealView.getMeasuredHeight();                                                 
3270             float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);         
3271                                                                                                          
3272             revealView.setTranslationY(0);                                                               
3273             revealView.setTranslationX(0);                                                               
3274                                                                                                          
3275             // Get the y delta between the center of the page and the center of the all apps button      
3276             int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                
3277                     getAllAppsButton(), null);                                                           
3278                                                                                                          
3279             float alpha = 0;                                                                             
3280             float xDrift = 0;                                                                            
3281             float yDrift = 0;                                                                            
3282             if (material) {                                                                              
3283                 alpha = isWidgetTray ? 0.3f : 1f;                                                        
3284                 yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                             
3285                 xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                      
3286             } else {                                                                                     
3287                 yDrift = 2 * height / 3;                                                                 
3288                 xDrift = 0;                                                                              
3289             }                                                                                            
3290             final float initAlpha = alpha;                                                               
3291                                                                                                          
3292             revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                     
3293             layerViews.add(revealView);                                                                  
3294             PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);      
3295             PropertyValuesHolder panelDriftY =                                                           
3296                     PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                             
3297             PropertyValuesHolder panelDriftX =                                                           
3298                     PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                             
3299                                                                                                          
3300             ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,        
3301                     panelAlpha, panelDriftY, panelDriftX);                                               
3302                                                                                                          
3303             panelAlphaAndDrift.setDuration(revealDuration);                                              
3304             panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                   
3305                                                                                                          
3306             mStateAnimation.play(panelAlphaAndDrift);                                                    
3307                                                                                                          
3308             if (page != null) {                                                                          
3309                 page.setVisibility(View.VISIBLE);                                                        
3310                 page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3311                 layerViews.add(page);                                                                    
3312                                                                                                          
3313                 ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);      
3314                 page.setTranslationY(yDrift);                                                            
3315                 pageDrift.setDuration(revealDuration);                                                   
3316                 pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                        
3317                 pageDrift.setStartDelay(itemsAlphaStagger);                                              
3318                 mStateAnimation.play(pageDrift);                                                         
3319                                                                                                          
3320                 page.setAlpha(0f);                                                                       
3321                 ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);               
3322                 itemsAlpha.setDuration(revealDuration);                                                  
3323                 itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                            
3324                 itemsAlpha.setStartDelay(itemsAlphaStagger);                                             
3325                 mStateAnimation.play(itemsAlpha);                                                        
3326             }                                                                                            
3327                                                                                                          
3328             View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);               
3329             pageIndicators.setAlpha(0.01f);                                                              
3330             ObjectAnimator indicatorsAlpha =                                                             
3331                     ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                 
3332             indicatorsAlpha.setDuration(revealDuration);                                                 
3333             mStateAnimation.play(indicatorsAlpha);                                                       
3334                                                                                                          
3335             if (material) {                                                                              
3336                 final View allApps = getAllAppsButton();                                                 
3337                 int allAppsButtonSize = LauncherAppState.getInstance().                                  
3338                         getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                     
3339                 float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                            
3340                 Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,         
3341                                 height / 2, startRadius, revealRadius);                                  
3342                 reveal.setDuration(revealDuration);                                                      
3343                 reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                           
3344                                                                                                          
3345                 reveal.addListener(new AnimatorListenerAdapter() {                                       
3346                     public void onAnimationStart(Animator animation) {                                   
3347                         if (!isWidgetTray) {                                                             
3348                             allApps.setVisibility(View.INVISIBLE);                                       
3349                         }                                                                                
3350                     }                                                                                    
3351                     public void onAnimationEnd(Animator animation) {                                     
3352                         if (!isWidgetTray) {                                                             
3353                             allApps.setVisibility(View.VISIBLE);                                         
3354                         }                                                                                
3355                     }                                                                                    
3356                 });                                                                                      
3357                 mStateAnimation.play(reveal);                                                            
3358             }                                                                                            
3359                                                                                                          
3360             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3361                 @Override                                                                                
3362                 public void onAnimationEnd(Animator animation) {                                         
3363                     dispatchOnLauncherTransitionEnd(fromView, animated, false);                          
3364                     dispatchOnLauncherTransitionEnd(toView, animated, false);                            
3365                                                                                                          
3366                     revealView.setVisibility(View.INVISIBLE);                                            
3367                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3368                     if (page != null) {                                                                  
3369                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3370                     }                                                                                    
3371                     content.setPageBackgroundsVisible(true);                                             
3372                                                                                                          
3373                     // Hide the search bar                                                               
3374                     if (mSearchDropTargetBar != null) {                                                  
3375                         mSearchDropTargetBar.hideSearchBar(false);                                       
3376                     }                                                                                    
3377                 }                                                                                        
3378                                                                                                          
3379             });                                                                                          
3380                                                                                                          
3381             if (workspaceAnim != null) {                                                                 
3382                 mStateAnimation.play(workspaceAnim);                                                     
3383             }                                                                                            
3384                                                                                                          
3385             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3386             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3387             final AnimatorSet stateAnimation = mStateAnimation;                                          
3388             final Runnable startAnimRunnable = new Runnable() {                                          
3389                 public void run() {                                                                      
3390                     // Check that mStateAnimation hasn't changed while                                   
3391                     // we waited for a layout/draw pass                                                  
3392                     if (mStateAnimation != stateAnimation)                                               
3393                         return;                                                                          
3394                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3395                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3396                                                                                                          
3397                     revealView.setAlpha(initAlpha);                                                      
3398                     if (Utilities.isLmpOrAbove()) {                                                      
3399                         for (int i = 0; i < layerViews.size(); i++) {                                    
3400                             View v = layerViews.get(i);                                                  
3401                             if (v != null) {                                                             
3402                                 boolean attached = true;                                                 
3403                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3404                                     attached = v.isAttachedToWindow();                                   
3405                                 }                                                                        
3406                                 if (attached) v.buildLayer();                                            
3407                             }                                                                            
3408                         }                                                                                
3409                     }                                                                                    
3410                     mStateAnimation.start();                                                             
3411                 }                                                                                        
3412             };                                                                                           
3413             toView.bringToFront();                                                                       
3414             toView.setVisibility(View.VISIBLE);                                                          
3415             toView.post(startAnimRunnable);                                                              
3416         } else {                                                                                         
3417             toView.setTranslationX(0.0f);                                                                
3418             toView.setTranslationY(0.0f);                                                                
3419             toView.setScaleX(1.0f);                                                                      
3420             toView.setScaleY(1.0f);                                                                      
3421             toView.setVisibility(View.VISIBLE);                                                          
3422             toView.bringToFront();                                                                       
3423                                                                                                          
3424             if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                      
3425                 // Hide the search bar                                                                   
3426                 if (mSearchDropTargetBar != null) {                                                      
3427                     mSearchDropTargetBar.hideSearchBar(false);                                           
3428                 }                                                                                        
3429             }                                                                                            
3430             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3431             dispatchOnLauncherTransitionStart(fromView, animated, false);                                
3432             dispatchOnLauncherTransitionEnd(fromView, animated, false);                                  
3433             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3434             dispatchOnLauncherTransitionStart(toView, animated, false);                                  
3435             dispatchOnLauncherTransitionEnd(toView, animated, false);                                    
3436         }                                                                                                
3437     }                                                                                                    
3438                                                                                                          
3439     /**                                                                                                  
3440      * Zoom the camera back into the workspace, hiding 'fromView'.                                       
3441      * This is the opposite of showAppsCustomizeHelper.                                                  
3442      * @param animated If true, the transition will be animated.                                         
3443      */                                                                                                  
3444     private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                
3445             final boolean springLoaded, final Runnable onCompleteRunnable) {                             
3446                                                                                                          
3447         if (mStateAnimation != null) {                                                                   
3448             mStateAnimation.setDuration(0);                                                              
3449             mStateAnimation.cancel();                                                                    
3450             mStateAnimation = null;                                                                      
3451         }                                                                                                
3452                                                                                                          
3453         boolean material = Utilities.isLmpOrAbove();                                                     
3454         Resources res = getResources();                                                                  
3455                                                                                                          
3456         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                  
3457         final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);           
3458         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);            
3459         final int itemsAlphaStagger =                                                                    
3460                 res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                         
3461                                                                                                          
3462         final float scaleFactor = (float)                                                                
3463                 res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                           
3464         final View fromView = mAppsCustomizeTabHost;                                                     
3465         final View toView = mWorkspace;                                                                  
3466         Animator workspaceAnim = null;                                                                   
3467         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3468                                                                                                          
3469         if (toState == Workspace.State.NORMAL) {                                                         
3470             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3471                     toState, animated, layerViews);                                                      
3472         } else if (toState == Workspace.State.SPRING_LOADED ||                                           
3473                 toState == Workspace.State.OVERVIEW) {                                                   
3474             workspaceAnim = mWorkspace.getChangeStateAnimation(                                          
3475                     toState, animated, layerViews);                                                      
3476         }                                                                                                
3477                                                                                                          
3478         // If for some reason our views aren't initialized, don't animate                                
3479         boolean initialized = getAllAppsButton() != null;                                                
3480                                                                                                          
3481         if (animated && initialized) {                                                                   
3482             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3483             if (workspaceAnim != null) {                                                                 
3484                 mStateAnimation.play(workspaceAnim);                                                     
3485             }                                                                                            
3486                                                                                                          
3487             final AppsCustomizePagedView content = (AppsCustomizePagedView)                              
3488                     fromView.findViewById(R.id.apps_customize_pane_content);                             
3489                                                                                                          
3490             final View page = content.getPageAt(content.getNextPage());                                  
3491                                                                                                          
3492             // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases        
3493             int count = content.getChildCount();                                                         
3494             for (int i = 0; i < count; i++) {                                                            
3495                 View child = content.getChildAt(i);                                                      
3496                 if (child != page) {                                                                     
3497                     child.setVisibility(View.INVISIBLE);                                                 
3498                 }                                                                                        
3499             }                                                                                            
3500             final View revealView = fromView.findViewById(R.id.fake_page);                               
3501                                                                                                          
3502             // hideAppsCustomizeHelper is called in some cases when it is already hidden                 
3503             // don't perform all these no-op animations. In particularly, this was causing               
3504             // the all-apps button to pop in and out.                                                    
3505             if (fromView.getVisibility() == View.VISIBLE) {                                              
3506                 AppsCustomizePagedView.ContentType contentType = content.getContentType();               
3507                 final boolean isWidgetTray =                                                             
3508                         contentType == AppsCustomizePagedView.ContentType.Widgets;                       
3509                                                                                                          
3510                 if (isWidgetTray) {                                                                      
3511                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));            
3512                 } else {                                                                                 
3513                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                 
3514                 }                                                                                        
3515                                                                                                          
3516                 int width = revealView.getMeasuredWidth();                                               
3517                 int height = revealView.getMeasuredHeight();                                             
3518                 float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);     
3519                                                                                                          
3520                 // Hide the real page background, and swap in the fake one                               
3521                 revealView.setVisibility(View.VISIBLE);                                                  
3522                 content.setPageBackgroundsVisible(false);                                                
3523                                                                                                          
3524                 final View allAppsButton = getAllAppsButton();                                           
3525                 revealView.setTranslationY(0);                                                           
3526                 int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,            
3527                         allAppsButton, null);                                                            
3528                                                                                                          
3529                 float xDrift = 0;                                                                        
3530                 float yDrift = 0;                                                                        
3531                 if (material) {                                                                          
3532                     yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                         
3533                     xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                  
3534                 } else {                                                                                 
3535                     yDrift = 5 * height / 4;                                                             
3536                     xDrift = 0;                                                                          
3537                 }                                                                                        
3538                                                                                                          
3539                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                 
3540                 TimeInterpolator decelerateInterpolator = material ?                                     
3541                         new LogDecelerateInterpolator(100, 0) :                                          
3542                         new LogDecelerateInterpolator(30, 0);                                            
3543                                                                                                          
3544                 // The vertical motion of the apps panel should be delayed by one frame                  
3545                 // from the conceal animation in order to give the right feel. We correpsondingly        
3546                 // shorten the duration so that the slide and conceal end at the same time.              
3547                 ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",       
3548                         0, yDrift);                                                                      
3549                 panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3550                 panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3551                 panelDriftY.setInterpolator(decelerateInterpolator);                                     
3552                 mStateAnimation.play(panelDriftY);                                                       
3553                                                                                                          
3554                 ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",       
3555                         0, xDrift);                                                                      
3556                 panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3557                 panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3558                 panelDriftX.setInterpolator(decelerateInterpolator);                                     
3559                 mStateAnimation.play(panelDriftX);                                                       
3560                                                                                                          
3561                 if (isWidgetTray || !material) {                                                         
3562                     float finalAlpha = material ? 0.4f : 0f;                                             
3563                     revealView.setAlpha(1f);                                                             
3564                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",           
3565                             1f, finalAlpha);                                                             
3566                     panelAlpha.setDuration(revealDuration);                                              
3567                     panelAlpha.setInterpolator(material ? decelerateInterpolator :                       
3568                         new AccelerateInterpolator(1.5f));                                               
3569                     mStateAnimation.play(panelAlpha);                                                    
3570                 }                                                                                        
3571                                                                                                          
3572                 if (page != null) {                                                                      
3573                     page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                   
3574                                                                                                          
3575                     ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",           
3576                             0, yDrift);                                                                  
3577                     page.setTranslationY(0);                                                             
3578                     pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                          
3579                     pageDrift.setInterpolator(decelerateInterpolator);                                   
3580                     pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                     
3581                     mStateAnimation.play(pageDrift);                                                     
3582                                                                                                          
3583                     page.setAlpha(1f);                                                                   
3584                     ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);        
3585                     itemsAlpha.setDuration(100);                                                         
3586                     itemsAlpha.setInterpolator(decelerateInterpolator);                                  
3587                     mStateAnimation.play(itemsAlpha);                                                    
3588                 }                                                                                        
3589                                                                                                          
3590                 View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);         
3591                 pageIndicators.setAlpha(1f);                                                             
3592                 ObjectAnimator indicatorsAlpha =                                                         
3593                         LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                          
3594                 indicatorsAlpha.setDuration(revealDuration);                                             
3595                 indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                       
3596                 mStateAnimation.play(indicatorsAlpha);                                                   
3597                                                                                                          
3598                 width = revealView.getMeasuredWidth();                                                   
3599                                                                                                          
3600                 if (material) {                                                                          
3601                     if (!isWidgetTray) {                                                                 
3602                         allAppsButton.setVisibility(View.INVISIBLE);                                     
3603                     }                                                                                    
3604                     int allAppsButtonSize = LauncherAppState.getInstance().                              
3605                             getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                 
3606                     float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                        
3607                     Animator reveal =                                                                    
3608                             LauncherAnimUtils.createCircularReveal(revealView, width / 2,                
3609                                     height / 2, revealRadius, finalRadius);                              
3610                     reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                       
3611                     reveal.setDuration(revealDuration);                                                  
3612                     reveal.setStartDelay(itemsAlphaStagger);                                             
3613                                                                                                          
3614                     reveal.addListener(new AnimatorListenerAdapter() {                                   
3615                         public void onAnimationEnd(Animator animation) {                                 
3616                             revealView.setVisibility(View.INVISIBLE);                                    
3617                             if (!isWidgetTray) {                                                         
3618                                 allAppsButton.setVisibility(View.VISIBLE);                               
3619                             }                                                                            
3620                         }                                                                                
3621                     });                                                                                  
3622                                                                                                          
3623                     mStateAnimation.play(reveal);                                                        
3624                 }                                                                                        
3625                                                                                                          
3626                 dispatchOnLauncherTransitionPrepare(fromView, animated, true);                           
3627                 dispatchOnLauncherTransitionPrepare(toView, animated, true);                             
3628                 mAppsCustomizeContent.stopScrolling();                                                   
3629             }                                                                                            
3630                                                                                                          
3631             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3632                 @Override                                                                                
3633                 public void onAnimationEnd(Animator animation) {                                         
3634                     fromView.setVisibility(View.GONE);                                                   
3635                     dispatchOnLauncherTransitionEnd(fromView, animated, true);                           
3636                     dispatchOnLauncherTransitionEnd(toView, animated, true);                             
3637                     if (onCompleteRunnable != null) {                                                    
3638                         onCompleteRunnable.run();                                                        
3639                     }                                                                                    
3640                                                                                                          
3641                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3642                     if (page != null) {                                                                  
3643                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3644                     }                                                                                    
3645                     content.setPageBackgroundsVisible(true);                                             
3646                     // Unhide side pages                                                                 
3647                     int count = content.getChildCount();                                                 
3648                     for (int i = 0; i < count; i++) {                                                    
3649                         View child = content.getChildAt(i);                                              
3650                         child.setVisibility(View.VISIBLE);                                               
3651                     }                                                                                    
3652                                                                                                          
3653                     // Reset page transforms                                                             
3654                     if (page != null) {                                                                  
3655                         page.setTranslationX(0);                                                         
3656                         page.setTranslationY(0);                                                         
3657                         page.setAlpha(1);                                                                
3658                     }                                                                                    
3659                     content.setCurrentPage(content.getNextPage());                                       
3660                                                                                                          
3661                     mAppsCustomizeContent.updateCurrentPageScroll();                                     
3662                 }                                                                                        
3663             });                                                                                          
3664                                                                                                          
3665             final AnimatorSet stateAnimation = mStateAnimation;                                          
3666             final Runnable startAnimRunnable = new Runnable() {                                          
3667                 public void run() {                                                                      
3668                     // Check that mStateAnimation hasn't changed while                                   
3669                     // we waited for a layout/draw pass                                                  
3670                     if (mStateAnimation != stateAnimation)                                               
3671                         return;                                                                          
3672                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3673                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3674                                                                                                          
3675                     if (Utilities.isLmpOrAbove()) {                                                      
3676                         for (int i = 0; i < layerViews.size(); i++) {                                    
3677                             View v = layerViews.get(i);                                                  
3678                             if (v != null) {                                                             
3679                                 boolean attached = true;                                                 
3680                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3681                                     attached = v.isAttachedToWindow();                                   
3682                                 }                                                                        
3683                                 if (attached) v.buildLayer();                                            
3684                             }                                                                            
3685                         }                                                                                
3686                     }                                                                                    
3687                     mStateAnimation.start();                                                             
3688                 }                                                                                        
3689             };                                                                                           
3690             fromView.post(startAnimRunnable);                                                            
3691         } else {                                                                                         
3692             fromView.setVisibility(View.GONE);                                                           
3693             dispatchOnLauncherTransitionPrepare(fromView, animated, true);                               
3694             dispatchOnLauncherTransitionStart(fromView, animated, true);                                 
3695             dispatchOnLauncherTransitionEnd(fromView, animated, true);                                   
3696             dispatchOnLauncherTransitionPrepare(toView, animated, true);                                 
3697             dispatchOnLauncherTransitionStart(toView, animated, true);                                   
3698             dispatchOnLauncherTransitionEnd(toView, animated, true);                                     
3699         }                                                                                                
3700     }                                                                                                    
3701                                                                                                          
3702     @Override                                                                                            
3703     public void onTrimMemory(int level) {                                                                
3704         super.onTrimMemory(level);                                                                       
3705         if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                         
3706             mAppsCustomizeTabHost.onTrimMemory();                                                        
3707         }                                                                                                
3708     }                                                                                                    
3709                                                                                                          
3710     protected void showWorkspace(boolean animated) {                                                     
3711         showWorkspace(animated, null);                                                                   
3712     }                                                                                                    
3713                                                                                                          
3714     protected void showWorkspace() {                                                                     
3715         showWorkspace(true);                                                                             
3716     }                                                                                                    
3717                                                                                                          
3718     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3719         if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {              
3720             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3721             mWorkspace.setVisibility(View.VISIBLE);                                                      
3722             hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);        
3723                                                                                                          
3724             // Show the search bar (only animate if we were showing the drop target bar in spring        
3725             // loaded mode)                                                                              
3726             if (mSearchDropTargetBar != null) {                                                          
3727                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3728             }                                                                                            
3729                                                                                                          
3730             // Set focus to the AppsCustomize button                                                     
3731             if (mAllAppsButton != null) {                                                                
3732                 mAllAppsButton.requestFocus();                                                           
3733             }                                                                                            
3734         }                                                                                                
3735                                                                                                          
3736         // Change the state *after* we've called all the transition code                                 
3737         mState = State.WORKSPACE;                                                                        
3738                                                                                                          
3739         // Resume the auto-advance of widgets                                                            
3740         mUserPresent = true;                                                                             
3741         updateRunning();                                                                                 
3742                                                                                                          
3743         // Send an accessibility event to announce the context change                                    
3744         getWindow().getDecorView()                                                                       
3745                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3746                                                                                                          
3747         onWorkspaceShown(animated);                                                                      
3748     }                                                                                                    
3749                                                                                                          
3750     void showOverviewMode(boolean animated) {                                                            
3751         mWorkspace.setVisibility(View.VISIBLE);                                                          
3752         hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                        
3753         mState = State.WORKSPACE;                                                                        
3754         onWorkspaceShown(animated);                                                                      
3755     }                                                                                                    
3756                                                                                                          
3757     public void onWorkspaceShown(boolean animated) {                                                     
3758     }                                                                                                    
3759                                                                                                          
3760     void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                   
3761                      boolean resetPageToZero) {                                                          
3762         if (mState != State.WORKSPACE) return;                                                           
3763                                                                                                          
3764         if (resetPageToZero) {                                                                           
3765             mAppsCustomizeTabHost.reset();                                                               
3766         }                                                                                                
3767         showAppsCustomizeHelper(animated, false, contentType);                                           
3768         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3769             @Override                                                                                    
3770             public void run() {                                                                          
3771                 // We post this in-case the all apps view isn't yet constructed.                         
3772                 mAppsCustomizeTabHost.requestFocus();                                                    
3773             }                                                                                            
3774         });                                                                                              
3775                                                                                                          
3776         // Change the state *after* we've called all the transition code                                 
3777         mState = State.APPS_CUSTOMIZE;                                                                   
3778                                                                                                          
3779         // Pause the auto-advance of widgets until we are out of AllApps                                 
3780         mUserPresent = false;                                                                            
3781         updateRunning();                                                                                 
3782         closeFolder();                                                                                   
3783                                                                                                          
3784         // Send an accessibility event to announce the context change                                    
3785         getWindow().getDecorView()                                                                       
3786                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3787     }                                                                                                    
3788                                                                                                          
3789     void enterSpringLoadedDragMode() {                                                                   
3790         if (isAllAppsVisible()) {                                                                        
3791             hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                    
3792             mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                 
3793         }                                                                                                
3794     }                                                                                                    
3795                                                                                                          
3796     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                        
3797             final Runnable onCompleteRunnable) {                                                         
3798         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                        
3799                                                                                                          
3800         mHandler.postDelayed(new Runnable() {                                                            
3801             @Override                                                                                    
3802             public void run() {                                                                          
3803                 if (successfulDrop) {                                                                    
3804                     // Before we show workspace, hide all apps again because                             
3805                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3806                     // clean up our state transition functions                                           
3807                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3808                     showWorkspace(true, onCompleteRunnable);                                             
3809                 } else {                                                                                 
3810                     exitSpringLoadedDragMode();                                                          
3811                 }                                                                                        
3812             }                                                                                            
3813         }, delay);                                                                                       
3814     }                                                                                                    
3815                                                                                                          
3816     void exitSpringLoadedDragMode() {                                                                    
3817         if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3818             final boolean animated = true;                                                               
3819             final boolean springLoaded = true;                                                           
3820             showAppsCustomizeHelper(animated, springLoaded);                                             
3821             mState = State.APPS_CUSTOMIZE;                                                               
3822         }                                                                                                
3823         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3824     }                                                                                                    
3825                                                                                                          
3826     void lockAllApps() {                                                                                 
3827         // TODO                                                                                          
3828     }                                                                                                    
3829                                                                                                          
3830     void unlockAllApps() {                                                                               
3831         // TODO                                                                                          
3832     }                                                                                                    
3833                                                                                                          
3834     /**                                                                                                  
3835      * Hides the hotseat area.                                                                           
3836      */                                                                                                  
3837     void hideHotseat(boolean animated) {                                                                 
3838         if (!LauncherAppState.getInstance().isScreenLarge()) {                                           
3839             if (animated) {                                                                              
3840                 if (mHotseat.getAlpha() != 0f) {                                                         
3841                     int duration = 0;                                                                    
3842                     if (mSearchDropTargetBar != null) {                                                  
3843                         duration = mSearchDropTargetBar.getTransitionOutDuration();                      
3844                     }                                                                                    
3845                     mHotseat.animate().alpha(0f).setDuration(duration);                                  
3846                 }                                                                                        
3847             } else {                                                                                     
3848                 mHotseat.setAlpha(0f);                                                                   
3849             }                                                                                            
3850         }                                                                                                
3851     }                                                                                                    
3852                                                                                                          
3853     /**                                                                                                  
3854      * Add an item from all apps or customize onto the given workspace screen.                           
3855      * If layout is null, add to the current screen.                                                     
3856      */                                                                                                  
3857     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                           
3858         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                     
3859             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
3860         }                                                                                                
3861     }                                                                                                    
3862                                                                                                          
3863     /** Maps the current orientation to an index for referencing orientation correct global icons */     
3864     private int getCurrentOrientationIndexForGlobalIcons() {                                             
3865         // default - 0, landscape - 1                                                                    
3866         switch (getResources().getConfiguration().orientation) {                                         
3867         case Configuration.ORIENTATION_LANDSCAPE:                                                        
3868             return 1;                                                                                    
3869         default:                                                                                         
3870             return 0;                                                                                    
3871         }                                                                                                
3872     }                                                                                                    
3873                                                                                                          
3874     private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {    
3875         try {                                                                                            
3876             PackageManager packageManager = getPackageManager();                                         
3877             // Look for the toolbar icon specified in the activity meta-data                             
3878             Bundle metaData = packageManager.getActivityInfo(                                            
3879                     activityName, PackageManager.GET_META_DATA).metaData;                                
3880             if (metaData != null) {                                                                      
3881                 int iconResId = metaData.getInt(resourceName);                                           
3882                 if (iconResId != 0) {                                                                    
3883                     Resources res = packageManager.getResourcesForActivity(activityName);                
3884                     return res.getDrawable(iconResId);                                                   
3885                 }                                                                                        
3886             }                                                                                            
3887         } catch (NameNotFoundException e) {                                                              
3888             // This can happen if the activity defines an invalid drawable                               
3889             Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +           
3890                     " not found", e);                                                                    
3891         } catch (Resources.NotFoundException nfe) {                                                      
3892             // This can happen if the activity defines an invalid drawable                               
3893             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),        
3894                     nfe);                                                                                
3895         }                                                                                                
3896         return null;                                                                                     
3897     }                                                                                                    
3898                                                                                                          
3899     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3900     private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                         
3901             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3902             String toolbarResourceName) {                                                                
3903         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3904         Resources r = getResources();                                                                    
3905         int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                            
3906         int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                           
3907                                                                                                          
3908         TextView button = (TextView) findViewById(buttonId);                                             
3909         // If we were unable to find the icon via the meta-data, use a generic one                       
3910         if (toolbarIcon == null) {                                                                       
3911             toolbarIcon = r.getDrawable(fallbackDrawableId);                                             
3912             toolbarIcon.setBounds(0, 0, w, h);                                                           
3913             if (button != null) {                                                                        
3914                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3915             }                                                                                            
3916             return null;                                                                                 
3917         } else {                                                                                         
3918             toolbarIcon.setBounds(0, 0, w, h);                                                           
3919             if (button != null) {                                                                        
3920                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3921             }                                                                                            
3922             return toolbarIcon.getConstantState();                                                       
3923         }                                                                                                
3924     }                                                                                                    
3925                                                                                                          
3926     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3927     private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                             
3928             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3929             String toolbarResourceName) {                                                                
3930         ImageView button = (ImageView) findViewById(buttonId);                                           
3931         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3932                                                                                                          
3933         if (button != null) {                                                                            
3934             // If we were unable to find the icon via the meta-data, use a                               
3935             // generic one                                                                               
3936             if (toolbarIcon == null) {                                                                   
3937                 button.setImageResource(fallbackDrawableId);                                             
3938             } else {                                                                                     
3939                 button.setImageDrawable(toolbarIcon);                                                    
3940             }                                                                                            
3941         }                                                                                                
3942                                                                                                          
3943         return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                              
3944                                                                                                          
3945     }                                                                                                    
3946                                                                                                          
3947     private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                
3948         TextView button = (TextView) findViewById(buttonId);                                             
3949         button.setCompoundDrawables(d, null, null, null);                                                
3950     }                                                                                                    
3951                                                                                                          
3952     private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                      
3953         ImageView button = (ImageView) findViewById(buttonId);                                           
3954         button.setImageDrawable(d.newDrawable(getResources()));                                          
3955     }                                                                                                    
3956                                                                                                          
3957     private void invalidatePressedFocusedStates(View container, View button) {                           
3958         if (container instanceof HolographicLinearLayout) {                                              
3959             HolographicLinearLayout layout = (HolographicLinearLayout) container;                        
3960             layout.invalidatePressedFocusedStates();                                                     
3961         } else if (button instanceof HolographicImageView) {                                             
3962             HolographicImageView view = (HolographicImageView) button;                                   
3963             view.invalidatePressedFocusedStates();                                                       
3964         }                                                                                                
3965     }                                                                                                    
3966                                                                                                          
3967     public View getQsbBar() {                                                                            
3968         if (mQsb == null) {                                                                              
3969             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                         
3970             mSearchDropTargetBar.addView(mQsb);                                                          
3971         }                                                                                                
3972         return mQsb;                                                                                     
3973     }                                                                                                    
3974                                                                                                          
3975     protected boolean updateGlobalSearchIcon() {                                                         
3976         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
3977         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                     
3978         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
3979         final View voiceButton = findViewById(R.id.voice_button);                                        
3980                                                                                                          
3981         final SearchManager searchManager =                                                              
3982                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
3983         ComponentName activityName = searchManager.getGlobalSearchActivity();                            
3984         if (activityName != null) {                                                                      
3985             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
3986             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                           
3987                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,             
3988                     TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                  
3989             if (sGlobalSearchIcon[coi] == null) {                                                        
3990                 sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                       
3991                         R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,         
3992                         TOOLBAR_ICON_METADATA_NAME);                                                     
3993             }                                                                                            
3994                                                                                                          
3995             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);        
3996             searchButton.setVisibility(View.VISIBLE);                                                    
3997             invalidatePressedFocusedStates(searchButtonContainer, searchButton);                         
3998             return true;                                                                                 
3999         } else {                                                                                         
4000             // We disable both search and voice search when there is no global search provider           
4001             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);           
4002             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4003             if (searchButton != null) searchButton.setVisibility(View.GONE);                             
4004             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4005             updateVoiceButtonProxyVisible(false);                                                        
4006             return false;                                                                                
4007         }                                                                                                
4008     }                                                                                                    
4009                                                                                                          
4010     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                    
4011         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
4012         final View searchButton = (ImageView) findViewById(R.id.search_button);                          
4013         updateButtonWithDrawable(R.id.search_button, d);                                                 
4014         invalidatePressedFocusedStates(searchButtonContainer, searchButton);                             
4015     }                                                                                                    
4016                                                                                                          
4017     protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                     
4018         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4019         final View voiceButton = findViewById(R.id.voice_button);                                        
4020                                                                                                          
4021         // We only show/update the voice search icon if the search icon is enabled as well               
4022         final SearchManager searchManager =                                                              
4023                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
4024         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
4025                                                                                                          
4026         ComponentName activityName = null;                                                               
4027         if (globalSearchActivity != null) {                                                              
4028             // Check if the global search activity handles voice search                                  
4029             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4030             intent.setPackage(globalSearchActivity.getPackageName());                                    
4031             activityName = intent.resolveActivity(getPackageManager());                                  
4032         }                                                                                                
4033                                                                                                          
4034         if (activityName == null) {                                                                      
4035             // Fallback: check if an activity other than the global search activity                      
4036             // resolves this                                                                             
4037             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
4038             activityName = intent.resolveActivity(getPackageManager());                                  
4039         }                                                                                                
4040         if (searchVisible && activityName != null) {                                                     
4041             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
4042             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                            
4043                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,               
4044                     TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                            
4045             if (sVoiceSearchIcon[coi] == null) {                                                         
4046                 sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                        
4047                         R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,           
4048                         TOOLBAR_ICON_METADATA_NAME);                                                     
4049             }                                                                                            
4050             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);          
4051             voiceButton.setVisibility(View.VISIBLE);                                                     
4052             updateVoiceButtonProxyVisible(false);                                                        
4053             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                           
4054             return true;                                                                                 
4055         } else {                                                                                         
4056             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
4057             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
4058             updateVoiceButtonProxyVisible(false);                                                        
4059             return false;                                                                                
4060         }                                                                                                
4061     }                                                                                                    
4062                                                                                                          
4063     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                     
4064         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
4065         final View voiceButton = findViewById(R.id.voice_button);                                        
4066         updateButtonWithDrawable(R.id.voice_button, d);                                                  
4067         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                               
4068     }                                                                                                    
4069                                                                                                          
4070     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                    
4071         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                             
4072         if (voiceButtonProxy != null) {                                                                  
4073             boolean visible = !forceDisableVoiceButtonProxy &&                                           
4074                     mWorkspace.shouldVoiceButtonProxyBeVisible();                                        
4075             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                          
4076             voiceButtonProxy.bringToFront();                                                             
4077         }                                                                                                
4078     }                                                                                                    
4079                                                                                                          
4080     /**                                                                                                  
4081      * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button🔵
4082      * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                      
4083      */                                                                                                  
4084     public void disableVoiceButtonProxy(boolean disabled) {                                              
4085         updateVoiceButtonProxyVisible(disabled);                                                         
4086     }                                                                                                    
4087                                                                                                          
4088     @Override                                                                                            
4089     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
4090         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
4091         final List<CharSequence> text = event.getText();                                                 
4092         text.clear();                                                                                    
4093         // Populate event with a fake title based on the current state.                                  
4094         if (mState == State.APPS_CUSTOMIZE) {                                                            
4095             text.add(mAppsCustomizeTabHost.getContentTag());                                             
4096         } else {                                                                                         
4097             text.add(getString(R.string.all_apps_home_button_label));                                    
4098         }                                                                                                
4099         return result;                                                                                   
4100     }                                                                                                    
4101                                                                                                          
4102     /**                                                                                                  
4103      * Receives notifications when system dialogs are to be closed.                                      
4104      */                                                                                                  
4105     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
4106         @Override                                                                                        
4107         public void onReceive(Context context, Intent intent) {                                          
4108             closeSystemDialogs();                                                                        
4109         }                                                                                                
4110     }                                                                                                    
4111                                                                                                          
4112     /**                                                                                                  
4113      * Receives notifications whenever the appwidgets are reset.                                         
4114      */                                                                                                  
4115     private class AppWidgetResetObserver extends ContentObserver {                                       
4116         public AppWidgetResetObserver() {                                                                
4117             super(new Handler());                                                                        
4118         }                                                                                                
4119                                                                                                          
4120         @Override                                                                                        
4121         public void onChange(boolean selfChange) {                                                       
4122             onAppWidgetReset();                                                                          
4123         }                                                                                                
4124     }                                                                                                    
4125                                                                                                          
4126     /**                                                                                                  
4127      * If the activity is currently paused, signal that we need to run the passed Runnable               
4128      * in onResume.                                                                                      
4129      *                                                                                                   
4130      * This needs to be called from incoming places where resources might have been loaded               
4131      * while we are paused.  That is becaues the Configuration might be wrong                            
4132      * when we're not running, and if it comes back to what it was when we                               
4133      * were paused, we are not restarted.                                                                
4134      *                                                                                                   
4135      * Implementation of the method from LauncherModel.Callbacks.                                        
4136      *                                                                                                   
4137      * @return true if we are currently paused.  The caller might be able to                             
4138      * skip some work in that case since we will come back again.                                        
4139      */                                                                                                  
4140     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
4141         if (mPaused) {                                                                                   
4142             Log.i(TAG, "Deferring update until onResume");                                               
4143             if (deletePreviousRunnables) {                                                               
4144                 while (mBindOnResumeCallbacks.remove(run)) {                                             
4145                 }                                                                                        
4146             }                                                                                            
4147             mBindOnResumeCallbacks.add(run);                                                             
4148             return true;                                                                                 
4149         } else {                                                                                         
4150             return false;                                                                                
4151         }                                                                                                
4152     }                                                                                                    
4153                                                                                                          
4154     private boolean waitUntilResume(Runnable run) {                                                      
4155         return waitUntilResume(run, false);                                                              
4156     }                                                                                                    
4157                                                                                                          
4158     public void addOnResumeCallback(Runnable run) {                                                      
4159         mOnResumeCallbacks.add(run);                                                                     
4160     }                                                                                                    
4161                                                                                                          
4162     /**                                                                                                  
4163      * If the activity is currently paused, signal that we need to re-run the loader                     
4164      * in onResume.                                                                                      
4165      *                                                                                                   
4166      * This needs to be called from incoming places where resources might have been loaded               
4167      * while we are paused.  That is becaues the Configuration might be wrong                            
4168      * when we're not running, and if it comes back to what it was when we                               
4169      * were paused, we are not restarted.                                                                
4170      *                                                                                                   
4171      * Implementation of the method from LauncherModel.Callbacks.                                        
4172      *                                                                                                   
4173      * @return true if we are currently paused.  The caller might be able to                             
4174      * skip some work in that case since we will come back again.                                        
4175      */                                                                                                  
4176     public boolean setLoadOnResume() {                                                                   
4177         if (mPaused) {                                                                                   
4178             Log.i(TAG, "setLoadOnResume");                                                               
4179             mOnResumeNeedsLoad = true;                                                                   
4180             return true;                                                                                 
4181         } else {                                                                                         
4182             return false;                                                                                
4183         }                                                                                                
4184     }                                                                                                    
4185                                                                                                          
4186     /**                                                                                                  
4187      * Implementation of the method from LauncherModel.Callbacks.                                        
4188      */                                                                                                  
4189     public int getCurrentWorkspaceScreen() {                                                             
4190         if (mWorkspace != null) {                                                                        
4191             return mWorkspace.getCurrentPage();                                                          
4192         } else {                                                                                         
4193             return SCREEN_COUNT / 2;                                                                     
4194         }                                                                                                
4195     }                                                                                                    
4196                                                                                                          
4197     /**                                                                                                  
4198      * Refreshes the shortcuts shown on the workspace.                                                   
4199      *                                                                                                   
4200      * Implementation of the method from LauncherModel.Callbacks.                                        
4201      */                                                                                                  
4202     public void startBinding() {                                                                         
4203         setWorkspaceLoading(true);                                                                       
4204                                                                                                          
4205         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4206         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4207         // from scratch again                                                                            
4208         mBindOnResumeCallbacks.clear();                                                                  
4209                                                                                                          
4210         // Clear the workspace because it's going to be rebound                                          
4211         mWorkspace.clearDropTargets();                                                                   
4212         mWorkspace.removeAllWorkspaceScreens();                                                          
4213                                                                                                          
4214         mWidgetsToAdvance.clear();                                                                       
4215         if (mHotseat != null) {                                                                          
4216             mHotseat.resetLayout();                                                                      
4217         }                                                                                                
4218     }                                                                                                    
4219                                                                                                          
4220     @Override                                                                                            
4221     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4222         bindAddScreens(orderedScreenIds);                                                                
4223                                                                                                          
4224         // If there are no screens, we need to have an empty screen                                      
4225         if (orderedScreenIds.size() == 0) {                                                              
4226             mWorkspace.addExtraEmptyScreen();                                                            
4227         }                                                                                                
4228                                                                                                          
4229         // Create the custom content page (this call updates mDefaultScreen which calls                  
4230         // setCurrentPage() so ensure that all pages are added before calling this).                     
4231         if (hasCustomContentToLeft()) {                                                                  
4232             mWorkspace.createCustomContentContainer();                                                   
4233             populateCustomContentContainer();                                                            
4234         }                                                                                                
4235     }                                                                                                    
4236                                                                                                          
4237     @Override                                                                                            
4238     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4239         // Log to disk                                                                                   
4240         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4241         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4242                 TextUtils.join(", ", orderedScreenIds), true);                                           
4243         int count = orderedScreenIds.size();                                                             
4244         for (int i = 0; i < count; i++) {                                                                
4245             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4246         }                                                                                                
4247     }                                                                                                    
4248                                                                                                          
4249     private boolean shouldShowWeightWatcher() {                                                          
4250         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4251         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4252         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4253                                                                                                          
4254         return show;                                                                                     
4255     }                                                                                                    
4256                                                                                                          
4257     private void toggleShowWeightWatcher() {                                                             
4258         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4259         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4260         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4261                                                                                                          
4262         show = !show;                                                                                    
4263                                                                                                          
4264         SharedPreferences.Editor editor = sp.edit();                                                     
4265         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4266         editor.commit();                                                                                 
4267                                                                                                          
4268         if (mWeightWatcher != null) {                                                                    
4269             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4270         }                                                                                                
4271     }                                                                                                    
4272                                                                                                          
4273     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
4274                               final ArrayList<ItemInfo> addNotAnimated,                                  
4275                               final ArrayList<ItemInfo> addAnimated,                                     
4276                               final ArrayList<AppInfo> addedApps) {                                      
4277         Runnable r = new Runnable() {                                                                    
4278             public void run() {                                                                          
4279                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4280             }                                                                                            
4281         };                                                                                               
4282         if (waitUntilResume(r)) {                                                                        
4283             return;                                                                                      
4284         }                                                                                                
4285                                                                                                          
4286         // Add the new screens                                                                           
4287         if (newScreens != null) {                                                                        
4288             bindAddScreens(newScreens);                                                                  
4289         }                                                                                                
4290                                                                                                          
4291         // We add the items without animation on non-visible pages, and with                             
4292         // animations on the new page (which we will try and snap to).                                   
4293         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
4294             bindItems(addNotAnimated, 0,                                                                 
4295                     addNotAnimated.size(), false);                                                       
4296         }                                                                                                
4297         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
4298             bindItems(addAnimated, 0,                                                                    
4299                     addAnimated.size(), true);                                                           
4300         }                                                                                                
4301                                                                                                          
4302         // Remove the extra empty screen                                                                 
4303         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4304                                                                                                          
4305         if (!LauncherAppState.isDisableAllApps() &&                                                      
4306                 addedApps != null && mAppsCustomizeContent != null) {                                    
4307             mAppsCustomizeContent.addApps(addedApps);                                                    
4308         }                                                                                                
4309     }                                                                                                    
4310                                                                                                          
4311     /**                                                                                                  
4312      * Bind the items start-end from the list.                                                           
4313      *                                                                                                   
4314      * Implementation of the method from LauncherModel.Callbacks.                                        
4315      */                                                                                                  
4316     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
4317                           final boolean forceAnimateIcons) {                                             
4318         Runnable r = new Runnable() {                                                                    
4319             public void run() {                                                                          
4320                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4321             }                                                                                            
4322         };                                                                                               
4323         if (waitUntilResume(r)) {                                                                        
4324             return;                                                                                      
4325         }                                                                                                
4326                                                                                                          
4327         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4328         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4329         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4330         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4331         Workspace workspace = mWorkspace;                                                                
4332         long newShortcutsScreenId = -1;                                                                  
4333         for (int i = start; i < end; i++) {                                                              
4334             final ItemInfo item = shortcuts.get(i);                                                      
4335                                                                                                          
4336             // Short circuit if we are loading dock items for a configuration which has no dock          
4337             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
4338                     mHotseat == null) {                                                                  
4339                 continue;                                                                                
4340             }                                                                                            
4341                                                                                                          
4342             switch (item.itemType) {                                                                     
4343                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
4344                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
4345                     ShortcutInfo info = (ShortcutInfo) item;                                             
4346                     View shortcut = createShortcut(info);                                                
4347                                                                                                          
4348                     /*                                                                                   
4349                      * TODO: FIX collision case                                                          
4350                      */                                                                                  
4351                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4352                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4353                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
4354                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4355                             Object tag = v.getTag();                                                     
4356                             String desc = "Collision while binding workspace item: " + item              
4357                                     + ". Collides with " + tag;                                          
4358                             if (LauncherAppState.isDogfoodBuild()) {                                     
4359                                 throw (new RuntimeException(desc));                                      
4360                             } else {                                                                     
4361                                 Log.d(TAG, desc);                                                        
4362                             }                                                                            
4363                         }                                                                                
4364                     }                                                                                    
4365                                                                                                          
4366                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
4367                             item.cellY, 1, 1);                                                           
4368                     if (animateIcons) {                                                                  
4369                         // Animate all the applications up now                                           
4370                         shortcut.setAlpha(0f);                                                           
4371                         shortcut.setScaleX(0f);                                                          
4372                         shortcut.setScaleY(0f);                                                          
4373                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4374                         newShortcutsScreenId = item.screenId;                                            
4375                     }                                                                                    
4376                     break;                                                                               
4377                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
4378                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
4379                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
4380                             (FolderInfo) item, mIconCache);                                              
4381                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
4382                             item.cellY, 1, 1);                                                           
4383                     break;                                                                               
4384                 default:                                                                                 
4385                     throw new RuntimeException("Invalid Item Type");                                     
4386             }                                                                                            
4387         }                                                                                                
4388                                                                                                          
4389         if (animateIcons) {                                                                              
4390             // Animate to the correct page                                                               
4391             if (newShortcutsScreenId > -1) {                                                             
4392                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4393                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4394                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4395                     public void run() {                                                                  
4396                         anim.playTogether(bounceAnims);                                                  
4397                         anim.start();                                                                    
4398                     }                                                                                    
4399                 };                                                                                       
4400                 if (newShortcutsScreenId != currentScreenId) {                                           
4401                     // We post the animation slightly delayed to prevent slowdowns                       
4402                     // when we are loading right after we return to launcher.                            
4403                     mWorkspace.postDelayed(new Runnable() {                                              
4404                         public void run() {                                                              
4405                             if (mWorkspace != null) {                                                    
4406                                 mWorkspace.snapToPage(newScreenIndex);                                   
4407                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
4408                                         NEW_APPS_ANIMATION_DELAY);                                       
4409                             }                                                                            
4410                         }                                                                                
4411                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4412                 } else {                                                                                 
4413                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4414                 }                                                                                        
4415             }                                                                                            
4416         }                                                                                                
4417         workspace.requestLayout();                                                                       
4418     }                                                                                                    
4419                                                                                                          
4420     /**                                                                                                  
4421      * Implementation of the method from LauncherModel.Callbacks.                                        
4422      */                                                                                                  
4423     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4424         Runnable r = new Runnable() {                                                                    
4425             public void run() {                                                                          
4426                 bindFolders(folders);                                                                    
4427             }                                                                                            
4428         };                                                                                               
4429         if (waitUntilResume(r)) {                                                                        
4430             return;                                                                                      
4431         }                                                                                                
4432         sFolders.clear();                                                                                
4433         sFolders.putAll(folders);                                                                        
4434     }                                                                                                    
4435                                                                                                          
4436     /**                                                                                                  
4437      * Add the views for a widget to the workspace.                                                      
4438      *                                                                                                   
4439      * Implementation of the method from LauncherModel.Callbacks.                                        
4440      */                                                                                                  
4441     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4442         Runnable r = new Runnable() {                                                                    
4443             public void run() {                                                                          
4444                 bindAppWidget(item);                                                                     
4445             }                                                                                            
4446         };                                                                                               
4447         if (waitUntilResume(r)) {                                                                        
4448             return;                                                                                      
4449         }                                                                                                
4450                                                                                                          
4451         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
4452         if (DEBUG_WIDGETS) {                                                                             
4453             Log.d(TAG, "bindAppWidget: " + item);                                                        
4454         }                                                                                                
4455         final Workspace workspace = mWorkspace;                                                          
4456                                                                                                          
4457         AppWidgetProviderInfo appWidgetInfo;                                                             
4458         if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&               
4459                 ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                 
4460                                                                                                          
4461             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);      
4462             if (appWidgetInfo == null) {                                                                 
4463                 if (DEBUG_WIDGETS) {                                                                     
4464                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4465                             + " belongs to component " + item.providerName                               
4466                             + ", as the povider is null");                                               
4467                 }                                                                                        
4468                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4469                 return;                                                                                  
4470             }                                                                                            
4471             // Note: This assumes that the id remap broadcast is received before this step.              
4472             // If that is not the case, the id remap will be ignored and user may see the                
4473             // click to setup view.                                                                      
4474             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);      
4475             pendingInfo.spanX = item.spanX;                                                              
4476             pendingInfo.spanY = item.spanY;                                                              
4477             pendingInfo.minSpanX = item.minSpanX;                                                        
4478             pendingInfo.minSpanY = item.minSpanY;                                                        
4479             Bundle options =                                                                             
4480                     AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                
4481                                                                                                          
4482             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4483             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
4484                     newWidgetId, appWidgetInfo, options);                                                
4485                                                                                                          
4486             // TODO consider showing a permission dialog when the widget is clicked.                     
4487             if (!success) {                                                                              
4488                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4489                 if (DEBUG_WIDGETS) {                                                                     
4490                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
4491                             + " belongs to component " + item.providerName                               
4492                             + ", as the launcher is unable to bing a new widget id");                    
4493                 }                                                                                        
4494                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4495                 return;                                                                                  
4496             }                                                                                            
4497                                                                                                          
4498             item.appWidgetId = newWidgetId;                                                              
4499                                                                                                          
4500             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4501             // the widget is ready to go.                                                                
4502             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4503                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4504                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4505                                                                                                          
4506             LauncherModel.updateItemInDatabase(this, item);                                              
4507         }                                                                                                
4508                                                                                                          
4509         if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                             
4510             final int appWidgetId = item.appWidgetId;                                                    
4511             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
4512             if (DEBUG_WIDGETS) {                                                                         
4513                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidget🔵
4514             }                                                                                            
4515                                                                                                          
4516             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4517         } else {                                                                                         
4518             appWidgetInfo = null;                                                                        
4519             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                    
4520             view.updateIcon(mIconCache);                                                                 
4521             item.hostView = view;                                                                        
4522             item.hostView.updateAppWidget(null);                                                         
4523             item.hostView.setOnClickListener(this);                                                      
4524         }                                                                                                
4525                                                                                                          
4526         item.hostView.setTag(item);                                                                      
4527         item.onBindAppWidget(this);                                                                      
4528                                                                                                          
4529         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4530                 item.cellY, item.spanX, item.spanY, false);                                              
4531         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
4532                                                                                                          
4533         workspace.requestLayout();                                                                       
4534                                                                                                          
4535         if (DEBUG_WIDGETS) {                                                                             
4536             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4537                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4538         }                                                                                                
4539     }                                                                                                    
4540                                                                                                          
4541     /**                                                                                                  
4542      * Restores a pending widget.                                                                        
4543      *                                                                                                   
4544      * @param appWidgetId The app widget id                                                              
4545      * @param cellInfo The position on screen where to create the widget.                                
4546      */                                                                                                  
4547     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4548         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4549         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4550             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4551             return;                                                                                      
4552         }                                                                                                
4553                                                                                                          
4554         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4555         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4556                                                                                                          
4557         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4558         LauncherModel.updateItemInDatabase(this, info);                                                  
4559     }                                                                                                    
4560                                                                                                          
4561     public void onPageBoundSynchronously(int page) {                                                     
4562         mSynchronouslyBoundPages.add(page);                                                              
4563     }                                                                                                    
4564                                                                                                          
4565     /**                                                                                                  
4566      * Callback saying that there aren't any more items to bind.                                         
4567      *                                                                                                   
4568      * Implementation of the method from LauncherModel.Callbacks.                                        
4569      */                                                                                                  
4570     public void finishBindingItems(final boolean upgradePath) {                                          
4571         Runnable r = new Runnable() {                                                                    
4572             public void run() {                                                                          
4573                 finishBindingItems(upgradePath);                                                         
4574             }                                                                                            
4575         };                                                                                               
4576         if (waitUntilResume(r)) {                                                                        
4577             return;                                                                                      
4578         }                                                                                                
4579         if (mSavedState != null) {                                                                       
4580             if (!mWorkspace.hasFocus()) {                                                                
4581                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4582             }                                                                                            
4583             mSavedState = null;                                                                          
4584         }                                                                                                
4585                                                                                                          
4586         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4587                                                                                                          
4588         setWorkspaceLoading(false);                                                                      
4589         sendLoadingCompleteBroadcastIfNecessary();                                                       
4590                                                                                                          
4591         // If we received the result of any pending adds while the loader was running (e.g. the          
4592         // widget configuration forced an orientation change), process them now.                         
4593         if (sPendingAddItem != null) {                                                                   
4594             final long screenId = completeAdd(sPendingAddItem);                                          
4595                                                                                                          
4596             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4597             // the screen would be guaranteed to exist after bind, and the page would be set through     
4598             // the workspace restore process.                                                            
4599             mWorkspace.post(new Runnable() {                                                             
4600                 @Override                                                                                
4601                 public void run() {                                                                      
4602                     mWorkspace.snapToScreenId(screenId);                                                 
4603                 }                                                                                        
4604             });                                                                                          
4605             sPendingAddItem = null;                                                                      
4606         }                                                                                                
4607                                                                                                          
4608         if (upgradePath) {                                                                               
4609             mWorkspace.getUniqueComponents(true, null);                                                  
4610             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4611         }                                                                                                
4612         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4613         mModel.recheckRestoredItems(this);                                                               
4614     }                                                                                                    
4615                                                                                                          
4616     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4617         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4618             String permission =                                                                          
4619                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4620             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4621             sendBroadcast(intent, permission);                                                           
4622             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4623             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4624             editor.apply();                                                                              
4625         }                                                                                                
4626     }                                                                                                    
4627                                                                                                          
4628     public boolean isAllAppsButtonRank(int rank) {                                                       
4629         if (mHotseat != null) {                                                                          
4630             return mHotseat.isAllAppsButtonRank(rank);                                                   
4631         }                                                                                                
4632         return false;                                                                                    
4633     }                                                                                                    
4634                                                                                                          
4635     private boolean canRunNewAppsAnimation() {                                                           
4636         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4637         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4638     }                                                                                                    
4639                                                                                                          
4640     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4641         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4642                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4643                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4644                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4645         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4646         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4647         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4648         return bounceAnim;                                                                               
4649     }                                                                                                    
4650                                                                                                          
4651     public boolean useVerticalBarLayout() {                                                              
4652         return LauncherAppState.getInstance().getDynamicGrid().                                          
4653                 getDeviceProfile().isVerticalBarLayout();                                                
4654     }                                                                                                    
4655                                                                                                          
4656     protected Rect getSearchBarBounds() {                                                                
4657         return LauncherAppState.getInstance().getDynamicGrid().                                          
4658                 getDeviceProfile().getSearchBarBounds();                                                 
4659     }                                                                                                    
4660                                                                                                          
4661     @Override                                                                                            
4662     public void bindSearchablesChanged() {                                                               
4663         boolean searchVisible = updateGlobalSearchIcon();                                                
4664         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
4665         if (mSearchDropTargetBar != null) {                                                              
4666             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
4667         }                                                                                                
4668     }                                                                                                    
4669                                                                                                          
4670     /**                                                                                                  
4671      * Add the icons for all apps.                                                                       
4672      *                                                                                                   
4673      * Implementation of the method from LauncherModel.Callbacks.                                        
4674      */                                                                                                  
4675     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4676         if (LauncherAppState.isDisableAllApps()) {                                                       
4677             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4678                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4679                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4680                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4681                 }                                                                                        
4682                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4683             }                                                                                            
4684             if (mAppsCustomizeContent != null) {                                                         
4685                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4686                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4687             }                                                                                            
4688         } else {                                                                                         
4689             if (mAppsCustomizeContent != null) {                                                         
4690                 mAppsCustomizeContent.setApps(apps);                                                     
4691                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4692                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4693             }                                                                                            
4694         }                                                                                                
4695     }                                                                                                    
4696                                                                                                          
4697     /**                                                                                                  
4698      * A package was updated.                                                                            
4699      *                                                                                                   
4700      * Implementation of the method from LauncherModel.Callbacks.                                        
4701      */                                                                                                  
4702     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4703         Runnable r = new Runnable() {                                                                    
4704             public void run() {                                                                          
4705                 bindAppsUpdated(apps);                                                                   
4706             }                                                                                            
4707         };                                                                                               
4708         if (waitUntilResume(r)) {                                                                        
4709             return;                                                                                      
4710         }                                                                                                
4711                                                                                                          
4712         if (mWorkspace != null) {                                                                        
4713             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4714         }                                                                                                
4715                                                                                                          
4716         if (!LauncherAppState.isDisableAllApps() &&                                                      
4717                 mAppsCustomizeContent != null) {                                                         
4718             mAppsCustomizeContent.updateApps(apps);                                                      
4719         }                                                                                                
4720     }                                                                                                    
4721                                                                                                          
4722     /**                                                                                                  
4723      * Packages were restored                                                                            
4724      */                                                                                                  
4725     public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                        
4726         Runnable r = new Runnable() {                                                                    
4727             public void run() {                                                                          
4728                 bindAppsRestored(apps);                                                                  
4729             }                                                                                            
4730         };                                                                                               
4731         if (waitUntilResume(r)) {                                                                        
4732             return;                                                                                      
4733         }                                                                                                
4734                                                                                                          
4735         if (mWorkspace != null) {                                                                        
4736             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4737         }                                                                                                
4738     }                                                                                                    
4739                                                                                                          
4740     /**                                                                                                  
4741      * Update the state of a package, typically related to install state.                                
4742      *                                                                                                   
4743      * Implementation of the method from LauncherModel.Callbacks.                                        
4744      */                                                                                                  
4745     @Override                                                                                            
4746     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4747         if (mWorkspace != null) {                                                                        
4748             mWorkspace.updatePackageState(installInfo);                                                  
4749         }                                                                                                
4750     }                                                                                                    
4751                                                                                                          
4752     /**                                                                                                  
4753      * Update the label and icon of all the icons in a package                                           
4754      *                                                                                                   
4755      * Implementation of the method from LauncherModel.Callbacks.                                        
4756      */                                                                                                  
4757     @Override                                                                                            
4758     public void updatePackageBadge(String packageName) {                                                 
4759         if (mWorkspace != null) {                                                                        
4760             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4761         }                                                                                                
4762     }                                                                                                    
4763                                                                                                          
4764     /**                                                                                                  
4765      * A package was uninstalled.  We take both the super set of packageNames                            
4766      * in addition to specific applications to remove, the reason being that                             
4767      * this can be called when a package is updated as well.  In that scenario,                          
4768      * we only remove specific components from the workspace, where as                                   
4769      * package-removal should clear all items by package name.                                           
4770      *                                                                                                   
4771      * Implementation of the method from LauncherModel.Callbacks.                                        
4772      */                                                                                                  
4773     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4774             final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {                            
4775         Runnable r = new Runnable() {                                                                    
4776             public void run() {                                                                          
4777                 bindComponentsRemoved(packageNames, appInfos, user);                                     
4778             }                                                                                            
4779         };                                                                                               
4780         if (waitUntilResume(r)) {                                                                        
4781             return;                                                                                      
4782         }                                                                                                
4783                                                                                                          
4784         if (!packageNames.isEmpty()) {                                                                   
4785             mWorkspace.removeItemsByPackageName(packageNames, user);                                     
4786         }                                                                                                
4787         if (!appInfos.isEmpty()) {                                                                       
4788             mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                     
4789         }                                                                                                
4790                                                                                                          
4791         // Notify the drag controller                                                                    
4792         mDragController.onAppsRemoved(packageNames, appInfos);                                           
4793                                                                                                          
4794         // Update AllApps                                                                                
4795         if (!LauncherAppState.isDisableAllApps() &&                                                      
4796                 mAppsCustomizeContent != null) {                                                         
4797             mAppsCustomizeContent.removeApps(appInfos);                                                  
4798         }                                                                                                
4799     }                                                                                                    
4800                                                                                                          
4801     /**                                                                                                  
4802      * A number of packages were updated.                                                                
4803      */                                                                                                  
4804     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4805     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4806             public void run() {                                                                          
4807                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4808                 mWidgetsAndShortcuts = null;                                                             
4809             }                                                                                            
4810         };                                                                                               
4811     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4812         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4813             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4814             return;                                                                                      
4815         }                                                                                                
4816                                                                                                          
4817         // Update the widgets pane                                                                       
4818         if (mAppsCustomizeContent != null) {                                                             
4819             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4820         }                                                                                                
4821     }                                                                                                    
4822                                                                                                          
4823     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4824         final Display d = getWindowManager().getDefaultDisplay();                                        
4825         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4826         switch (d.getRotation()) {                                                                       
4827         case Surface.ROTATION_0:                                                                         
4828         case Surface.ROTATION_180:                                                                       
4829             // We are currently in the same basic orientation as the natural orientation                 
4830             naturalOri = configOri;                                                                      
4831             break;                                                                                       
4832         case Surface.ROTATION_90:                                                                        
4833         case Surface.ROTATION_270:                                                                       
4834             // We are currently in the other basic orientation to the natural orientation                
4835             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4836                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4837             break;                                                                                       
4838         }                                                                                                
4839                                                                                                          
4840         int[] oriMap = {                                                                                 
4841                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4842                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4843                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4844                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4845         };                                                                                               
4846         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4847         // is landscape.                                                                                 
4848         int indexOffset = 0;                                                                             
4849         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4850             indexOffset = 1;                                                                             
4851         }                                                                                                
4852         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4853     }                                                                                                    
4854                                                                                                          
4855     public boolean isRotationEnabled() {                                                                 
4856         boolean enableRotation = sForceEnableRotation ||                                                 
4857                 getResources().getBoolean(R.bool.allow_rotation);                                        
4858         return enableRotation;                                                                           
4859     }                                                                                                    
4860     public void lockScreenOrientation() {                                                                
4861         if (isRotationEnabled()) {                                                                       
4862             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                    
4863                     .getConfiguration().orientation));                                                   
4864         }                                                                                                
4865     }                                                                                                    
4866     public void unlockScreenOrientation(boolean immediate) {                                             
4867         if (isRotationEnabled()) {                                                                       
4868             if (immediate) {                                                                             
4869                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4870             } else {                                                                                     
4871                 mHandler.postDelayed(new Runnable() {                                                    
4872                     public void run() {                                                                  
4873                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4874                     }                                                                                    
4875                 }, mRestoreScreenOrientationDelay);                                                      
4876             }                                                                                            
4877         }                                                                                                
4878     }                                                                                                    
4879                                                                                                          
4880     /**                                                                                                  
4881      * Called when the SearchBar hint should be changed.                                                 
4882      *                                                                                                   
4883      * @param hint the hint to be displayed in the search bar.                                           
4884      */                                                                                                  
4885     protected void onSearchBarHintChanged(String hint) {                                                 
4886                                                                                                          
4887     }                                                                                                    
4888                                                                                                          
4889     protected boolean isLauncherPreinstalled() {                                                         
4890         PackageManager pm = getPackageManager();                                                         
4891         try {                                                                                            
4892             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4893             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4894                 return true;                                                                             
4895             } else {                                                                                     
4896                 return false;                                                                            
4897             }                                                                                            
4898         } catch (NameNotFoundException e) {                                                              
4899             e.printStackTrace();                                                                         
4900             return false;                                                                                
4901         }                                                                                                
4902     }                                                                                                    
4903                                                                                                          
4904     /**                                                                                                  
4905      * This method indicates whether or not we should suggest default wallpaper dimensions               
4906      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4907      */                                                                                                  
4908     protected boolean overrideWallpaperDimensions() {                                                    
4909         return true;                                                                                     
4910     }                                                                                                    
4911                                                                                                          
4912     protected boolean shouldClingFocusHotseatApp() {                                                     
4913         return false;                                                                                    
4914     }                                                                                                    
4915     protected String getFirstRunClingSearchBarHint() {                                                   
4916         return "";                                                                                       
4917     }                                                                                                    
4918     protected String getFirstRunCustomContentHint() {                                                    
4919         return "";                                                                                       
4920     }                                                                                                    
4921     protected int getFirstRunFocusedHotseatAppDrawableId() {                                             
4922         return -1;                                                                                       
4923     }                                                                                                    
4924     protected ComponentName getFirstRunFocusedHotseatAppComponentName() {                                
4925         return null;                                                                                     
4926     }                                                                                                    
4927     protected int getFirstRunFocusedHotseatAppRank() {                                                   
4928         return -1;                                                                                       
4929     }                                                                                                    
4930     protected String getFirstRunFocusedHotseatAppBubbleTitle() {                                         
4931         return "";                                                                                       
4932     }                                                                                                    
4933     protected String getFirstRunFocusedHotseatAppBubbleDescription() {                                   
4934         return "";                                                                                       
4935     }                                                                                                    
4936                                                                                                          
4937     /**                                                                                                  
4938      * To be overridden by subclasses to indicate that there is an activity to launch                    
4939      * before showing the standard launcher experience.                                                  
4940      */                                                                                                  
4941     protected boolean hasFirstRunActivity() {                                                            
4942         return false;                                                                                    
4943     }                                                                                                    
4944                                                                                                          
4945     /**                                                                                                  
4946      * To be overridden by subclasses to launch any first run activity                                   
4947      */                                                                                                  
4948     protected Intent getFirstRunActivity() {                                                             
4949         return null;                                                                                     
4950     }                                                                                                    
4951                                                                                                          
4952     private boolean shouldRunFirstRunActivity() {                                                        
4953         return !ActivityManager.isRunningInTestHarness() &&                                              
4954                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4955     }                                                                                                    
4956                                                                                                          
4957     protected boolean hasRunFirstRunActivity() {                                                         
4958         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4959     }                                                                                                    
4960                                                                                                          
4961     public boolean showFirstRunActivity() {                                                              
4962         if (shouldRunFirstRunActivity() &&                                                               
4963                 hasFirstRunActivity()) {                                                                 
4964             Intent firstRunIntent = getFirstRunActivity();                                               
4965             if (firstRunIntent != null) {                                                                
4966                 startActivity(firstRunIntent);                                                           
4967                 markFirstRunActivityShown();                                                             
4968                 return true;                                                                             
4969             }                                                                                            
4970         }                                                                                                
4971         return false;                                                                                    
4972     }                                                                                                    
4973                                                                                                          
4974     private void markFirstRunActivityShown() {                                                           
4975         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4976         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4977         editor.apply();                                                                                  
4978     }                                                                                                    
4979                                                                                                          
4980     /**                                                                                                  
4981      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4982      * screen that must be displayed and dismissed.                                                      
4983      */                                                                                                  
4984     protected boolean hasDismissableIntroScreen() {                                                      
4985         return false;                                                                                    
4986     }                                                                                                    
4987                                                                                                          
4988     /**                                                                                                  
4989      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4990      */                                                                                                  
4991     protected View getIntroScreen() {                                                                    
4992         return null;                                                                                     
4993     }                                                                                                    
4994                                                                                                          
4995     /**                                                                                                  
4996      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4997      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4998      */                                                                                                  
4999     private boolean shouldShowIntroScreen() {                                                            
5000         return hasDismissableIntroScreen() &&                                                            
5001                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
5002     }                                                                                                    
5003                                                                                                          
5004     protected void showIntroScreen() {                                                                   
5005         View introScreen = getIntroScreen();                                                             
5006         changeWallpaperVisiblity(false);                                                                 
5007         if (introScreen != null) {                                                                       
5008             mDragLayer.showOverlayView(introScreen);                                                     
5009         }                                                                                                
5010     }                                                                                                    
5011                                                                                                          
5012     public void dismissIntroScreen() {                                                                   
5013         markIntroScreenDismissed();                                                                      
5014         if (showFirstRunActivity()) {                                                                    
5015             // We delay hiding the intro view until the first run activity is showing. This              
5016             // avoids a blip.                                                                            
5017             mWorkspace.postDelayed(new Runnable() {                                                      
5018                 @Override                                                                                
5019                 public void run() {                                                                      
5020                     mDragLayer.dismissOverlayView();                                                     
5021                     showFirstRunClings();                                                                
5022                 }                                                                                        
5023             }, ACTIVITY_START_DELAY);                                                                    
5024         } else {                                                                                         
5025             mDragLayer.dismissOverlayView();                                                             
5026             showFirstRunClings();                                                                        
5027         }                                                                                                
5028         changeWallpaperVisiblity(true);                                                                  
5029     }                                                                                                    
5030                                                                                                          
5031     private void markIntroScreenDismissed() {                                                            
5032         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
5033         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
5034         editor.apply();                                                                                  
5035     }                                                                                                    
5036                                                                                                          
5037     private void showFirstRunClings() {                                                                  
5038         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
5039         // on the device, then we always show the first run cling experience (or if there is no          
5040         // launcher2). Otherwise, we prompt the user upon started for migration                          
5041         LauncherClings launcherClings = new LauncherClings(this);                                        
5042         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
5043             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
5044                 launcherClings.showMigrationCling();                                                     
5045             } else {                                                                                     
5046                 launcherClings.showLongPressCling(true);                                                 
5047             }                                                                                            
5048         }                                                                                                
5049     }                                                                                                    
5050                                                                                                          
5051     void showWorkspaceSearchAndHotseat() {                                                               
5052         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
5053         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
5054         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
5055         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
5056     }                                                                                                    
5057                                                                                                          
5058     void hideWorkspaceSearchAndHotseat() {                                                               
5059         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
5060         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
5061         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
5062         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
5063     }                                                                                                    
5064                                                                                                          
5065     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
5066         // Called from search suggestion, not supported in other profiles.                               
5067         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
5068         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
5069         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
5070                 myUser);                                                                                 
5071         if (activityInfo == null) {                                                                      
5072             return null;                                                                                 
5073         }                                                                                                
5074         return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                
5075     }                                                                                                    
5076                                                                                                          
5077     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5078             Bitmap icon) {                                                                               
5079         // Called from search suggestion, not supported in other profiles.                               
5080         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
5081                 UserHandleCompat.myUserHandle());                                                        
5082     }                                                                                                    
5083                                                                                                          
5084     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
5085             Bitmap icon, UserHandleCompat user) {                                                        
5086         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
5087         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
5088         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
5089     }                                                                                                    
5090                                                                                                          
5091     protected void moveWorkspaceToDefaultScreen() {                                                      
5092         mWorkspace.moveToDefaultScreen(false);                                                           
5093     }                                                                                                    
5094                                                                                                          
5095     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
5096         dragView.setTag(dragInfo);                                                                       
5097         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
5098         mWorkspace.beginExternalDragShared(dragView, source);                                            
5099     }                                                                                                    
5100                                                                                                          
5101     @Override                                                                                            
5102     public void onPageSwitch(View newPage, int newPageIndex) {                                           
5103     }                                                                                                    
5104                                                                                                          
5105     /**                                                                                                  
5106      * Prints out out state for debugging.                                                               
5107      */                                                                                                  
5108     public void dumpState() {                                                                            
5109         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
5110         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
5111         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
5112         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
5113         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
5114         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
5115         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
5116         mModel.dumpState();                                                                              
5117                                                                                                          
5118         if (mAppsCustomizeContent != null) {                                                             
5119             mAppsCustomizeContent.dumpState();                                                           
5120         }                                                                                                
5121         Log.d(TAG, "END launcher3 dump state");                                                          
5122     }                                                                                                    
5123                                                                                                          
5124     @Override                                                                                            
5125     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
5126         super.dump(prefix, fd, writer, args);                                                            
5127         synchronized (sDumpLogs) {                                                                       
5128             writer.println(" ");                                                                         
5129             writer.println("Debug logs: ");                                                              
5130             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
5131                 writer.println("  " + sDumpLogs.get(i));                                                 
5132             }                                                                                            
5133         }                                                                                                
5134     }                                                                                                    
5135                                                                                                          
5136     public static void dumpDebugLogsToConsole() {                                                        
5137         if (DEBUG_DUMP_LOG) {                                                                            
5138             synchronized (sDumpLogs) {                                                                   
5139                 Log.d(TAG, "");                                                                          
5140                 Log.d(TAG, "*********************");                                                     
5141                 Log.d(TAG, "Launcher debug logs: ");                                                     
5142                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
5143                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
5144                 }                                                                                        
5145                 Log.d(TAG, "*********************");                                                     
5146                 Log.d(TAG, "");                                                                          
5147             }                                                                                            
5148         }                                                                                                
5149     }                                                                                                    
5150                                                                                                          
5151     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
5152         addDumpLog(tag, log, null, debugLog);                                                            
5153     }                                                                                                    
5154                                                                                                          
5155     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
5156         if (debugLog) {                                                                                  
5157             if (e != null) {                                                                             
5158                 Log.d(tag, log, e);                                                                      
5159             } else {                                                                                     
5160                 Log.d(tag, log);                                                                         
5161             }                                                                                            
5162         }                                                                                                
5163         if (DEBUG_DUMP_LOG) {                                                                            
5164             sDateStamp.setTime(System.currentTimeMillis());                                              
5165             synchronized (sDumpLogs) {                                                                   
5166                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
5167                     + (e == null ? "" : (", Exception: " + e)));                                         
5168             }                                                                                            
5169         }                                                                                                
5170     }                                                                                                    
5171                                                                                                          
5172     public void dumpLogsToLocalData() {                                                                  
5173         if (DEBUG_DUMP_LOG) {                                                                            
5174             new AsyncTask<Void, Void, Void>() {                                                          
5175                 public Void doInBackground(Void ... args) {                                              
5176                     boolean success = false;                                                             
5177                     sDateStamp.setTime(sRunStart);                                                       
5178                     String FILENAME = sDateStamp.getMonth() + "-"                                        
5179                             + sDateStamp.getDay() + "_"                                                  
5180                             + sDateStamp.getHours() + "-"                                                
5181                             + sDateStamp.getMinutes() + "_"                                              
5182                             + sDateStamp.getSeconds() + ".txt";                                          
5183                                                                                                          
5184                     FileOutputStream fos = null;                                                         
5185                     File outFile = null;                                                                 
5186                     try {                                                                                
5187                         outFile = new File(getFilesDir(), FILENAME);                                     
5188                         outFile.createNewFile();                                                         
5189                         fos = new FileOutputStream(outFile);                                             
5190                     } catch (Exception e) {                                                              
5191                         e.printStackTrace();                                                             
5192                     }                                                                                    
5193                     if (fos != null) {                                                                   
5194                         PrintWriter writer = new PrintWriter(fos);                                       
5195                                                                                                          
5196                         writer.println(" ");                                                             
5197                         writer.println("Debug logs: ");                                                  
5198                         synchronized (sDumpLogs) {                                                       
5199                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
5200                                 writer.println("  " + sDumpLogs.get(i));                                 
5201                             }                                                                            
5202                         }                                                                                
5203                         writer.close();                                                                  
5204                     }                                                                                    
5205                     try {                                                                                
5206                         if (fos != null) {                                                               
5207                             fos.close();                                                                 
5208                             success = true;                                                              
5209                         }                                                                                
5210                     } catch (IOException e) {                                                            
5211                         e.printStackTrace();                                                             
5212                     }                                                                                    
5213                     return null;                                                                         
5214                 }                                                                                        
5215             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
5216         }                                                                                                
5217     }                                                                                                    
5218 }                                                                                                        
5219                                                                                                          
5220 interface LauncherTransitionable {                                                                       
5221     View getContent();                                                                                   
5222     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
5223     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
5224     void onLauncherTransitionStep(Launcher l, float t);                                                  
5225     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
5226 }                                                                                                        
5227                                                                                                          
5228 interface DebugIntents {                                                                                 
5229     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
5230     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
5231 }                                                                                                        




































































































































































































































































































































































































































































































































































   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16 package com.android.launcher3;                                                                           
  17                                                                                                          
  18 import android.animation.Animator;                                                                       
  19 import android.animation.AnimatorListenerAdapter;                                                        
  20 import android.animation.AnimatorSet;                                                                    
  21 import android.animation.ObjectAnimator;                                                                 
  22 import android.animation.PropertyValuesHolder;                                                           
  23 import android.animation.TimeInterpolator;                                                               
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.SharedPreferences;                                                                
  44 import android.content.pm.ActivityInfo;                                                                  
  45 import android.content.pm.ApplicationInfo;                                                               
  46 import android.content.pm.PackageManager.NameNotFoundException;                                          
  47 import android.content.pm.PackageManager;                                                                
  48 import android.content.res.Configuration;                                                                
  49 import android.content.res.Resources;                                                                    
  50 import android.database.ContentObserver;                                                                 
  51 import android.graphics.Bitmap;                                                                          
  52 import android.graphics.Canvas;                                                                          
  53 import android.graphics.Color;                                                                           
  54 import android.graphics.Point;                                                                           
  55 import android.graphics.PorterDuff;                                                                      
  56 import android.graphics.Rect;                                                                            
  57 import android.graphics.drawable.Drawable;                                                               
  58 import android.net.Uri;                                                                                  
  59 import android.os.AsyncTask;                                                                             
  60 import android.os.Build;                                                                                 
  61 import android.os.Bundle;                                                                                
  62 import android.os.Environment;                                                                           
  63 import android.os.Handler;                                                                               
  64 import android.os.Message;                                                                               
  65 import android.os.StrictMode;                                                                            
  66 import android.os.SystemClock;                                                                           
  67 import android.speech.RecognizerIntent;                                                                  
  68 import android.text.Selection;                                                                           
  69 import android.text.SpannableStringBuilder;                                                              
  70 import android.text.TextUtils;                                                                           
  71 import android.text.method.TextKeyListener;                                                              
  72 import android.util.DisplayMetrics;                                                                      
  73 import android.util.Log;                                                                                 
  74 import android.view.ContextThemeWrapper;                                                                 
  75 import android.view.Display;                                                                             
  76 import android.view.Gravity;                                                                             
  77 import android.view.HapticFeedbackConstants;                                                             
  78 import android.view.KeyEvent;                                                                            
  79 import android.view.LayoutInflater;                                                                      
  80 import android.view.Menu;                                                                                
  81 import android.view.MotionEvent;                                                                         
  82 import android.view.Surface;                                                                             
  83 import android.view.View.OnClickListener;                                                                
  84 import android.view.View.OnLongClickListener;                                                            
  85 import android.view.View;                                                                                
  86 import android.view.ViewAnimationUtils;                                                                  
  87 import android.view.ViewGroup;                                                                           
  88 import android.view.ViewTreeObserver.OnGlobalLayoutListener;                                             
  89 import android.view.ViewTreeObserver;                                                                    
  90 import android.view.Window;                                                                              
  91 import android.view.WindowManager;                                                                       
  92 import android.view.accessibility.AccessibilityEvent;                                                    
  93 import android.view.animation.AccelerateInterpolator;                                                    
  94 import android.view.animation.DecelerateInterpolator;                                                    
  95 import android.view.animation.Interpolator;                                                              
  96 import android.view.inputmethod.InputMethodManager;                                                      
  97 import android.widget.Advanceable;                                                                       
  98 import android.widget.FrameLayout;                                                                       
  99 import android.widget.ImageView;                                                                         
 100 import android.widget.TextView;                                                                          
 101 import android.widget.Toast;                                                                             
 102 import com.android.launcher3.DropTarget.DragObject;                                                      
 103 import com.android.launcher3.PagedView.PageSwitchListener;                                               
 104 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
 105 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 106 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 107 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 108 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 109 import com.android.launcher3.compat.UserHandleCompat;                                                    
 110 import com.android.launcher3.compat.UserManagerCompat;                                                   
 111 import java.io.DataInputStream;                                                                          
 112 import java.io.DataOutputStream;                                                                         
 113 import java.io.File;                                                                                     
 114 import java.io.FileDescriptor;                                                                           
 115 import java.io.FileNotFoundException;                                                                    
 116 import java.io.FileOutputStream;                                                                         
 117 import java.io.IOException;                                                                              
 118 import java.io.PrintWriter;                                                                              
 119 import java.lang.reflect.Field;                                                                          
 120 import java.lang.reflect.InvocationTargetException;                                                      
 121 import java.lang.reflect.Method;                                                                         
 122 import java.text.DateFormat;                                                                             
 123 import java.util.ArrayList;                                                                              
 124 import java.util.Collection;                                                                             
 125 import java.util.Date;                                                                                   
 126 import java.util.HashMap;                                                                                
 127 import java.util.List;                                                                                   
 128 import java.util.concurrent.atomic.AtomicInteger;                                                        
 129                                                                                                          
 130                                                                                                          
 131 interface DebugIntents {                                                                                 
 132     public static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";         
 133                                                                                                          
 134     public static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";       
 135 }                                                                                                        
 136                                                                                                          
 137 /**                                                                                                      
 138  * Default launcher application.                                                                         
 139  */                                                                                                      
 140 public class Launcher extends Activity implements View.OnClickListener , OnLongClickListener , LauncherMo🔵
 141     static final String TAG = "Launcher";                                                                
 142                                                                                                          
 143     static final boolean LOGD = false;                                                                   
 144                                                                                                          
 145     static final boolean PROFILE_STARTUP = false;                                                        
 146                                                                                                          
 147     static final boolean DEBUG_WIDGETS = false;                                                          
 148                                                                                                          
 149     static final boolean DEBUG_STRICT_MODE = false;                                                      
 150                                                                                                          
 151     static final boolean DEBUG_RESUME_TIME = false;                                                      
 152                                                                                                          
 153     static final boolean DEBUG_DUMP_LOG = false;                                                         
 154                                                                                                          
 155     // allow DebugIntents to run                                                                         
 156     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 157                                                                                                          
 158     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 159                                                                                                          
 160     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 161                                                                                                          
 162     private static final int REQUEST_PICK_SHORTCUT = 7;                                                  
 163                                                                                                          
 164     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 165                                                                                                          
 166     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 167                                                                                                          
 168     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 169                                                                                                          
 170     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 171                                                                                                          
 172     /**                                                                                                  
 173      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 174      * request codes used internally.                                                                    
 175      */                                                                                                  
 176     protected static final int REQUEST_LAST = 100;                                                       
 177                                                                                                          
 178     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 179                                                                                                          
 180     static final int SCREEN_COUNT = 5;                                                                   
 181                                                                                                          
 182     static final int DEFAULT_SCREEN = 2;                                                                 
 183                                                                                                          
 184     private static final String PREFERENCES = "launcher.preferences";                                    
 185                                                                                                          
 186     // To turn on these properties, type                                                                 
 187     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 188     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                        
 189                                                                                                          
 190     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 191                                                                                                          
 192     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                
 193                                                                                                          
 194     // The Intent extra that defines whether to ignore the launch animation                              
 195     // The Intent extra that defines whether to ignore the launch animation                              
 196     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 197             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 198                                                                                                          
 199     // Type: int                                                                                         
 200     // Type: int                                                                                         
 201     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 202                                                                                                          
 203     // Type: int                                                                                         
 204     // Type: int                                                                                         
 205     private static final String RUNTIME_STATE = "launcher.state";                                        
 206                                                                                                          
 207     // Type: int                                                                                         
 208     // Type: int                                                                                         
 209     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 210                                                                                                          
 211     // Type: int                                                                                         
 212     // Type: int                                                                                         
 213     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 214                                                                                                          
 215     // Type: int                                                                                         
 216     // Type: int                                                                                         
 217     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 218                                                                                                          
 219     // Type: int                                                                                         
 220     // Type: int                                                                                         
 221     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 222                                                                                                          
 223     // Type: boolean                                                                                     
 224     // Type: boolean                                                                                     
 225     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 226                                                                                                          
 227     // Type: long                                                                                        
 228     // Type: long                                                                                        
 229     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 230                                                                                                          
 231     // Type: int                                                                                         
 232     // Type: int                                                                                         
 233     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 234                                                                                                          
 235     // Type: int                                                                                         
 236     // Type: int                                                                                         
 237     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 238                                                                                                          
 239     // Type: parcelable                                                                                  
 240     // Type: parcelable                                                                                  
 241     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 242                                                                                                          
 243     // Type: parcelable                                                                                  
 244     // Type: parcelable                                                                                  
 245     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 246                                                                                                          
 247     // Type: int[]                                                                                       
 248     // Type: int[]                                                                                       
 249     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 250                                                                                                          
 251     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 252                                                                                                          
 253     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 254                                                                                                          
 255     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 256                                                                                                          
 257     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 258             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 259                                                                                                          
 260     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";        
 261                                                                                                          
 262     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                      
 263             "com.android.launcher.toolbar_search_icon";                                                  
 264                                                                                                          
 265     private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                
 266             "com.android.launcher.toolbar_voice_search_icon";                                            
 267                                                                                                          
 268     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 269                                                                                                          
 270     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 271                                                                                                          
 272     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 273                                                                                                          
 274     /**                                                                                                  
 275      * The different states that Launcher can be in.                                                     
 276      */                                                                                                  
 277     private enum State {                                                                                 
 278                                                                                                          
 279         NONE,                                                                                            
 280         WORKSPACE,                                                                                       
 281         APPS_CUSTOMIZE,                                                                                  
 282         APPS_CUSTOMIZE_SPRING_LOADED;}                                                                   
 283                                                                                                          
 284     private State mState = State.WORKSPACE;                                                              
 285                                                                                                          
 286     private AnimatorSet mStateAnimation;                                                                 
 287                                                                                                          
 288     private boolean mIsSafeModeEnabled;                                                                  
 289                                                                                                          
 290     static final int APPWIDGET_HOST_ID = 1024;                                                           
 291                                                                                                          
 292     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 293                                                                                                          
 294     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 295                                                                                                          
 296     private static final int ACTIVITY_START_DELAY = 1000;                                                
 297                                                                                                          
 298     private static final Object sLock = new Object();                                                    
 299                                                                                                          
 300     private static int sScreen = DEFAULT_SCREEN;                                                         
 301                                                                                                          
 302     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 303                                                                                                          
 304     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 305                                                                                                          
 306     // How long to wait before the new-shortcut animation automatically pans the workspace               
 307     // How long to wait before the new-shortcut animation automatically pans the workspace               
 308     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 309                                                                                                          
 310     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 311                                                                                                          
 312     private static int NEW_APPS_ANIMATION_DELAY = 500;                                                   
 313                                                                                                          
 314     private static final int SINGLE_FRAME_DELAY = 16;                                                    
 315                                                                                                          
 316     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 317             = new CloseSystemDialogsIntentReceiver();                                                    
 318                                                                                                          
 319     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 320                                                                                                          
 321     private LayoutInflater mInflater;                                                                    
 322                                                                                                          
 323     private Workspace mWorkspace;                                                                        
 324                                                                                                          
 325     private View mLauncherView;                                                                          
 326                                                                                                          
 327     private View mPageIndicators;                                                                        
 328                                                                                                          
 329     private DragLayer mDragLayer;                                                                        
 330                                                                                                          
 331     private DragController mDragController;                                                              
 332                                                                                                          
 333     private View mWeightWatcher;                                                                         
 334                                                                                                          
 335     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 336                                                                                                          
 337     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 338                                                                                                          
 339     private ItemInfo mPendingAddInfo = new ItemInfo();                                                   
 340                                                                                                          
 341     private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                 
 342                                                                                                          
 343     private int mPendingAddWidgetId = -1;                                                                
 344                                                                                                          
 345     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 346                                                                                                          
 347     private FolderInfo mFolderInfo;                                                                      
 348                                                                                                          
 349     private Hotseat mHotseat;                                                                            
 350                                                                                                          
 351     private ViewGroup mOverviewPanel;                                                                    
 352                                                                                                          
 353     private View mAllAppsButton;                                                                         
 354                                                                                                          
 355     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 356                                                                                                          
 357     private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                  
 358                                                                                                          
 359     private AppsCustomizePagedView mAppsCustomizeContent;                                                
 360                                                                                                          
 361     private boolean mAutoAdvanceRunning = false;                                                         
 362                                                                                                          
 363     private View mQsb;                                                                                   
 364                                                                                                          
 365     private Bundle mSavedState;                                                                          
 366                                                                                                          
 367     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 368     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 369     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 370     private State mOnResumeState = State.NONE;                                                           
 371                                                                                                          
 372     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 373                                                                                                          
 374     private boolean mWorkspaceLoading = true;                                                            
 375                                                                                                          
 376     private boolean mPaused = true;                                                                      
 377                                                                                                          
 378     private boolean mRestoring;                                                                          
 379                                                                                                          
 380     private boolean mWaitingForResult;                                                                   
 381                                                                                                          
 382     private boolean mOnResumeNeedsLoad;                                                                  
 383                                                                                                          
 384     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 385                                                                                                          
 386     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 387                                                                                                          
 388     private Bundle mSavedInstanceState;                                                                  
 389                                                                                                          
 390     private LauncherModel mModel;                                                                        
 391                                                                                                          
 392     private IconCache mIconCache;                                                                        
 393                                                                                                          
 394     private boolean mUserPresent = true;                                                                 
 395                                                                                                          
 396     private boolean mVisible = false;                                                                    
 397                                                                                                          
 398     private boolean mHasFocus = false;                                                                   
 399                                                                                                          
 400     private boolean mAttached = false;                                                                   
 401                                                                                                          
 402     private static LocaleConfiguration sLocaleConfiguration = null;                                      
 403                                                                                                          
 404     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 405                                                                                                          
 406     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 407                                                                                                          
 408     // Related to the auto-advancing of widgets                                                          
 409     // Related to the auto-advancing of widgets                                                          
 410     private final int ADVANCE_MSG = 1;                                                                   
 411                                                                                                          
 412     private final int mAdvanceInterval = 20000;                                                          
 413                                                                                                          
 414     private final int mAdvanceStagger = 250;                                                             
 415                                                                                                          
 416     private long mAutoAdvanceSentTime;                                                                   
 417                                                                                                          
 418     private long mAutoAdvanceTimeLeft = -1;                                                              
 419                                                                                                          
 420     private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance = new HashMap<View, AppWidgetProviderI🔵
 421                                                                                                          
 422     // Determines how long to wait after a rotation before restoring the screen orientation to           
 423     // match the sensor state.                                                                           
 424     // Determines how long to wait after a rotation before restoring the screen orientation to           
 425     // match the sensor state.                                                                           
 426     private final int mRestoreScreenOrientationDelay = 500;                                              
 427                                                                                                          
 428     // External icons saved in case of resource changes, orientation, etc.                               
 429     private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];           
 430                                                                                                          
 431     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];            
 432                                                                                                          
 433     private Drawable mWorkspaceBackgroundDrawable;                                                       
 434                                                                                                          
 435     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 436                                                                                                          
 437     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 438                                                                                                          
 439     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 440                                                                                                          
 441     static Date sDateStamp = new Date();                                                                 
 442                                                                                                          
 443     static DateFormat sDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);  
 444                                                                                                          
 445     static long sRunStart = System.currentTimeMillis();                                                  
 446                                                                                                          
 447     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 448                                                                                                          
 449     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 450     // it from the context.                                                                              
 451     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 452     // it from the context.                                                                              
 453     private SharedPreferences mSharedPrefs;                                                              
 454                                                                                                          
 455     private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                   
 456                                                                                                          
 457     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 458     // when we scroll to that page on resume.                                                            
 459     private ImageView mFolderIconImageView;                                                              
 460                                                                                                          
 461     private Bitmap mFolderIconBitmap;                                                                    
 462                                                                                                          
 463     private Canvas mFolderIconCanvas;                                                                    
 464                                                                                                          
 465     private Rect mRectForFolderAnimation = new Rect();                                                   
 466                                                                                                          
 467     private BubbleTextView mWaitingForResume;                                                            
 468                                                                                                          
 469     private Runnable mBuildLayersRunnable = new Runnable() {                                             
 470         public void run() {                                                                              
 471             if (mWorkspace != null) {                                                                    
 472                 mWorkspace.buildPageHardwareLayers();                                                    
 473             }                                                                                            
 474         }                                                                                                
 475     };                                                                                                   
 476                                                                                                          
 477     private static PendingAddArguments sPendingAddItem;                                                  
 478                                                                                                          
 479     public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);      
 480                                                                                                          
 481     private static class PendingAddArguments {                                                           
 482         int requestCode;                                                                                 
 483                                                                                                          
 484         Intent intent;                                                                                   
 485                                                                                                          
 486         long container;                                                                                  
 487                                                                                                          
 488         long screenId;                                                                                   
 489                                                                                                          
 490         int cellX;                                                                                       
 491                                                                                                          
 492         int cellY;                                                                                       
 493                                                                                                          
 494         int appWidgetId;                                                                                 
 495     }                                                                                                    
 496                                                                                                          
 497     private Stats mStats;                                                                                
 498                                                                                                          
 499     FocusIndicatorView mFocusHandler;                                                                    
 500                                                                                                          
 501     static boolean isPropertyEnabled(String propertyName) {                                              
 502         return Log.isLoggable(propertyName, Log.VERBOSE);                                                
 503     }                                                                                                    
 504                                                                                                          
 505     @Override                                                                                            
 506     protected void onCreate(Bundle savedInstanceState) {                                                 
 507         if (DEBUG_STRICT_MODE) {                                                                         
 508             StrictMode.setThreadPolicy(// or .detectAll() for all detectable problems                    
 509             new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().pe🔵
 510             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectL🔵
 511         }                                                                                                
 512         super.onCreate(savedInstanceState);                                                              
 513         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 514         LauncherAppState app = LauncherAppState.getInstance();                                           
 515         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 516         // Determine the dynamic grid properties                                                         
 517         Point smallestSize = new Point();                                                                
 518         Point largestSize = new Point();                                                                 
 519         Point realSize = new Point();                                                                    
 520         Display display = getWindowManager().getDefaultDisplay();                                        
 521         display.getCurrentSizeRange(smallestSize, largestSize);                                          
 522         display.getRealSize(realSize);                                                                   
 523         DisplayMetrics dm = new DisplayMetrics();                                                        
 524         display.getMetrics(dm);                                                                          
 525         // Lazy-initialize the dynamic grid                                                              
 526         DeviceProfile grid = app.initDynamicGrid(this, Math.min(smallestSize.x, smallestSize.y), Math.min🔵
 527         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 528         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIV🔵
 529         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 530         mModel = app.setLauncher(this);                                                                  
 531         mIconCache = app.getIconCache();                                                                 
 532         mIconCache.flushInvalidIcons(grid);                                                              
 533         mDragController = new DragController(this);                                                      
 534         mInflater = getLayoutInflater();                                                                 
 535         mStats = new Stats(this);                                                                        
 536         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 537         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 538         mAppWidgetHost.startListening();                                                                 
 539         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 540         // this also ensures that any synchronous binding below doesn't re-trigger another               
 541         // LauncherModel load.                                                                           
 542         mPaused = false;                                                                                 
 543         if (PROFILE_STARTUP) {                                                                           
 544             android.os.Debug.startMethodTracing(Environment.getExternalStorageDirectory() + "/launcher");
 545         }                                                                                                
 546         checkForLocaleChange();                                                                          
 547         setContentView(R.layout.launcher);                                                               
 548         setupViews();                                                                                    
 549         grid.layout(this);                                                                               
 550         registerContentObservers();                                                                      
 551         lockAllApps();                                                                                   
 552         mSavedState = savedInstanceState;                                                                
 553         restoreState(mSavedState);                                                                       
 554         if (PROFILE_STARTUP) {                                                                           
 555             android.os.Debug.stopMethodTracing();                                                        
 556         }                                                                                                
 557         if (!mRestoring) {                                                                               
 558             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 559                 // If the user leaves launcher, then we should just load items asynchronously when       
 560                 // they return.                                                                          
 561                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 562             } else {                                                                                     
 563                 // We only load the page synchronously if the user rotates (or triggers a                
 564                 // configuration change) while launcher is in the foreground                             
 565                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 566             }                                                                                            
 567         }                                                                                                
 568         // For handling default keys                                                                     
 569         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 570         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 571         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 572         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 573         updateGlobalIcons();                                                                             
 574         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 575         unlockScreenOrientation(true);                                                                   
 576         if (shouldShowIntroScreen()) {                                                                   
 577             showIntroScreen();                                                                           
 578         } else {                                                                                         
 579             showFirstRunActivity();                                                                      
 580             showFirstRunClings();                                                                        
 581         }                                                                                                
 582     }                                                                                                    
 583                                                                                                          
 584     @Override                                                                                            
 585     public void onLauncherProviderChange() { }                                                           
 586                                                                                                          
 587     /** To be overriden by subclasses to hint to Launcher that we have custom content */                 
 588     protected boolean hasCustomContentToLeft() {                                                         
 589         return false;                                                                                    
 590     }                                                                                                    
 591                                                                                                          
 592     /**                                                                                                  
 593      * To be overridden by subclasses to populate the custom content container and call                  
 594      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 595      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 596      */                                                                                                  
 597     protected void populateCustomContentContainer() {                                                    
 598     }                                                                                                    
 599                                                                                                          
 600     /**                                                                                                  
 601      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 602      * ensure the custom content page is added or removed if necessary.                                  
 603      */                                                                                                  
 604     protected void invalidateHasCustomContentToLeft() {                                                  
 605         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 606             // Not bound yet, wait for bindScreens to be called.                                         
 607             return;                                                                                      
 608         }                                                                                                
 609                                                                                                          
 610         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 611             // Create the custom content page and call the subclass to populate it.                      
 612             mWorkspace.createCustomContentContainer();                                                   
 613             populateCustomContentContainer();                                                            
 614         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 615             mWorkspace.removeCustomContentPage();                                                        
 616         }                                                                                                
 617     }                                                                                                    
 618                                                                                                          
 619     private void updateGlobalIcons() {                                                                   
 620         boolean searchVisible = false;                                                                   
 621         boolean voiceVisible = false;                                                                    
 622         // If we have a saved version of these external icons, we load them up immediately               
 623         int coi = getCurrentOrientationIndexForGlobalIcons();                                            
 624         if ((sGlobalSearchIcon[coi] == null) || (sVoiceSearchIcon[coi] == null)) {                       
 625             searchVisible = updateGlobalSearchIcon();                                                    
 626             voiceVisible = updateVoiceSearchIcon(searchVisible);                                         
 627         }                                                                                                
 628         if (sGlobalSearchIcon[coi] != null) {                                                            
 629             updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                              
 630             searchVisible = true;                                                                        
 631         }                                                                                                
 632         if (sVoiceSearchIcon[coi] != null) {                                                             
 633             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                
 634             voiceVisible = true;                                                                         
 635         }                                                                                                
 636         if (mSearchDropTargetBar != null) {                                                              
 637             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
 638         }                                                                                                
 639     }                                                                                                    
 640                                                                                                          
 641     private void checkForLocaleChange() {                                                                
 642         if (sLocaleConfiguration == null) {                                                              
 643             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 644                 @Override                                                                                
 645                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 646                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 647                     readConfiguration(Launcher.this, localeConfiguration);                               
 648                     return localeConfiguration;                                                          
 649                 }                                                                                        
 650                                                                                                          
 651                 @Override                                                                                
 652                 protected void onPostExecute(LocaleConfiguration result) {                               
 653                     sLocaleConfiguration = result;                                                       
 654                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 655                 }                                                                                        
 656             }.execute();                                                                                 
 657             return;                                                                                      
 658         }                                                                                                
 659                                                                                                          
 660         final Configuration configuration = getResources().getConfiguration();                           
 661                                                                                                          
 662         final String previousLocale = sLocaleConfiguration.locale;                                       
 663         final String locale = configuration.locale.toString();                                           
 664                                                                                                          
 665         final int previousMcc = sLocaleConfiguration.mcc;                                                
 666         final int mcc = configuration.mcc;                                                               
 667                                                                                                          
 668         final int previousMnc = sLocaleConfiguration.mnc;                                                
 669         final int mnc = configuration.mnc;                                                               
 670                                                                                                          
 671         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 672                                                                                                          
 673         if (localeChanged) {                                                                             
 674             sLocaleConfiguration.locale = locale;                                                        
 675             sLocaleConfiguration.mcc = mcc;                                                              
 676             sLocaleConfiguration.mnc = mnc;                                                              
 677                                                                                                          
 678             mIconCache.flush();                                                                          
 679                                                                                                          
 680             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 681             new AsyncTask<Void, Void, Void>() {                                                          
 682                 public Void doInBackground(Void ... args) {                                              
 683                     writeConfiguration(Launcher.this, localeConfiguration);                              
 684                     return null;                                                                         
 685                 }                                                                                        
 686             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 687         }                                                                                                
 688     }                                                                                                    
 689                                                                                                          
 690     private static class LocaleConfiguration {                                                           
 691         public String locale;                                                                            
 692                                                                                                          
 693         public int mcc = -1;                                                                             
 694                                                                                                          
 695         public int mnc = -1;                                                                             
 696     }                                                                                                    
 697                                                                                                          
 698     private static void readConfiguration(Context context, LocaleConfiguration configuration) {          
 699         DataInputStream in = null;                                                                       
 700         try {                                                                                            
 701             in = new DataInputStream(context.openFileInput(PREFERENCES));                                
 702             configuration.locale = in.readUTF();                                                         
 703             configuration.mcc = in.readInt();                                                            
 704             configuration.mnc = in.readInt();                                                            
 705         } catch (FileNotFoundException e) {                                                              
 706             // Ignore                                                                                    
 707         } catch (IOException e) {                                                                        
 708             // Ignore                                                                                    
 709         } finally {                                                                                      
 710             if (in != null) {                                                                            
 711                 try {                                                                                    
 712                     in.close();                                                                          
 713                 } catch (IOException e) {                                                                
 714                     // Ignore                                                                            
 715                 }                                                                                        
 716             }                                                                                            
 717         }                                                                                                
 718     }                                                                                                    
 719                                                                                                          
 720     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {         
 721         DataOutputStream out = null;                                                                     
 722         try {                                                                                            
 723             out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));               
 724             out.writeUTF(configuration.locale);                                                          
 725             out.writeInt(configuration.mcc);                                                             
 726             out.writeInt(configuration.mnc);                                                             
 727             out.flush();                                                                                 
 728         } catch (FileNotFoundException e) {                                                              
 729             // Ignore                                                                                    
 730         } catch (IOException e) {                                                                        
 731             //noinspection ResultOfMethodCallIgnored                                                     
 732             context.getFileStreamPath(PREFERENCES).delete();                                             
 733         } finally {                                                                                      
 734             if (out != null) {                                                                           
 735                 try {                                                                                    
 736                     out.close();                                                                         
 737                 } catch (IOException e) {                                                                
 738                     // Ignore                                                                            
 739                 }                                                                                        
 740             }                                                                                            
 741         }                                                                                                
 742     }                                                                                                    
 743                                                                                                          
 744     public Stats getStats() {                                                                            
 745         return mStats;                                                                                   
 746     }                                                                                                    
 747                                                                                                          
 748     public LayoutInflater getInflater() {                                                                
 749         return mInflater;                                                                                
 750     }                                                                                                    
 751                                                                                                          
 752     boolean isDraggingEnabled() {                                                                        
 753         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 754         // that is subsequently removed from the workspace in startBinding().                            
 755         return !mModel.isLoadingWorkspace();                                                             
 756     }                                                                                                    
 757                                                                                                          
 758     static int getScreen() {                                                                             
 759         synchronized (sLock) {                                                                           
 760             return sScreen;                                                                              
 761         }                                                                                                
 762     }                                                                                                    
 763                                                                                                          
 764     static void setScreen(int screen) {                                                                  
 765         synchronized (sLock) {                                                                           
 766             sScreen = screen;                                                                            
 767         }                                                                                                
 768     }                                                                                                    
 769                                                                                                          
 770     public static int generateViewId() {                                                                 
 771         if (Build.VERSION.SDK_INT >= 17) {                                                               
 772             return View.generateViewId();                                                                
 773         } else {                                                                                         
 774             // View.generateViewId() is not available. The following fallback logic is a copy            
 775             // of its implementation.                                                                    
 776             for (; ;) {                                                                                  
 777                 final int result = sNextGeneratedId.get();                                               
 778                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 779                 int newValue = result + 1;                                                               
 780                 if (newValue > 0xffffff) {                                                               
 781                     newValue = 1;                                                                        
 782                 }// Roll over to 1, not 0.                                                               
 783                                                                                                          
 784                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 785                     return result;                                                                       
 786                 }                                                                                        
 787             }                                                                                            
 788         }                                                                                                
 789     }                                                                                                    
 790                                                                                                          
 791     public int getViewIdForItem(ItemInfo info) {                                                         
 792         // This cast is safe given the > 2B range for int.                                               
 793         int itemId = (int) info.id;                                                                      
 794         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 795             return mItemIdToViewId.get(itemId);                                                          
 796         }                                                                                                
 797         int viewId = generateViewId();                                                                   
 798         mItemIdToViewId.put(itemId, viewId);                                                             
 799         return viewId;                                                                                   
 800     }                                                                                                    
 801                                                                                                          
 802     /**                                                                                                  
 803      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 804      * a configuration step, this allows the proper animations to run after other transitions.           
 805      */                                                                                                  
 806     private long completeAdd(PendingAddArguments args) {                                                 
 807         long screenId = args.screenId;                                                                   
 808         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 809             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 810             // that the drop page actually exists.                                                       
 811             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 812         }                                                                                                
 813         switch (args.requestCode) {                                                                      
 814             case REQUEST_CREATE_SHORTCUT :                                                               
 815                 completeAddShortcut(args.intent, args.container, screenId, args.cellX, args.cellY);      
 816                 break;                                                                                   
 817             case REQUEST_CREATE_APPWIDGET :                                                              
 818                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 819                 break;                                                                                   
 820             case REQUEST_RECONFIGURE_APPWIDGET :                                                         
 821                 completeRestoreAppWidget(args.appWidgetId);                                              
 822                 break;                                                                                   
 823         }                                                                                                
 824         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 825         // if you turned the screen off and then back while in All Apps, Launcher would not              
 826         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 827         resetAddInfo();                                                                                  
 828         return screenId;                                                                                 
 829     }                                                                                                    
 830                                                                                                          
 831     @Override                                                                                            
 832     protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {    
 833         // Reset the startActivity waiting flag                                                          
 834         setWaitingForResult(false);                                                                      
 835         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 836         mPendingAddWidgetId = -1;                                                                        
 837         Runnable exitSpringLoaded = new Runnable() {                                                     
 838             @Override                                                                                    
 839             public void run() {                                                                          
 840                 exitSpringLoadedDragModeDelayed(resultCode != RESULT_CANCELED, EXIT_SPRINGLOADED_MODE_SHO🔵
 841             }                                                                                            
 842         };                                                                                               
 843         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 844             final int appWidgetId = (data != null) ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID🔵
 845             if (resultCode == RESULT_CANCELED) {                                                         
 846                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 847                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded, ON_ACTIVITY_RESULT_ANIMA🔵
 848             } else if (resultCode == RESULT_OK) {                                                        
 849                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null, mPendingAddWidgetInfo, ON_ACTIVITY_R🔵
 850             }                                                                                            
 851             return;                                                                                      
 852         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 853             if ((resultCode == RESULT_OK) && mWorkspace.isInOverviewMode()) {                            
 854                 mWorkspace.exitOverviewMode(false);                                                      
 855             }                                                                                            
 856             return;                                                                                      
 857         }                                                                                                
 858         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET) || (requestCode == REQUEST_CREATE_🔵
 859         final boolean workspaceLocked = isWorkspaceLocked();                                             
 860         // We have special handling for widgets                                                          
 861         if (isWidgetDrop) {                                                                              
 862             final int appWidgetId;                                                                       
 863             int widgetId = (data != null) ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -🔵
 864             if (widgetId < 0) {                                                                          
 865                 appWidgetId = pendingAddWidgetId;                                                        
 866             } else {                                                                                     
 867                 appWidgetId = widgetId;                                                                  
 868             }                                                                                            
 869             final int result;                                                                            
 870             if ((appWidgetId < 0) || (resultCode == RESULT_CANCELED)) {                                  
 871                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " + "returned from the widget🔵
 872                 result = RESULT_CANCELED;                                                                
 873                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 874                 final Runnable onComplete = new Runnable() {                                             
 875                     @Override                                                                            
 876                     public void run() {                                                                  
 877                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 878                     }                                                                                    
 879                 };                                                                                       
 880                 if (workspaceLocked) {                                                                   
 881                     // No need to remove the empty screen if we're mid-binding, as the                   
 882                     // the bind will not add the empty screen.                                           
 883                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 884                 } else {                                                                                 
 885                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, ON_ACTIVITY_RESULT_ANIMATI🔵
 886                 }                                                                                        
 887             } else if (!workspaceLocked) {                                                               
 888                 if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {         
 889                         // When the screen id represents an actual screen (as opposed to a rank)         
 890                         // we make sure that the drop page actually exists.                              
 891                     mPendingAddInfo.screenId = ensurePendingDropLayoutExists(mPendingAddInfo.screenId);  
 892                 }                                                                                        
 893                 final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);      
 894                 dropLayout.setDropPending(true);                                                         
 895                 final Runnable onComplete = new Runnable() {                                             
 896                     @Override                                                                            
 897                     public void run() {                                                                  
 898                         completeTwoStageWidgetDrop(resultCode, appWidgetId);                             
 899                         dropLayout.setDropPending(false);                                                
 900                     }                                                                                    
 901                 };                                                                                       
 902                 mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, ON_ACTIVITY_RESULT_ANIMATION_D🔵
 903             } else {                                                                                     
 904                 PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId, mPending🔵
 905                 sPendingAddItem = args;                                                                  
 906             }                                                                                            
 907             return;                                                                                      
 908         }                                                                                                
 909         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 910             if (resultCode == RESULT_OK) {                                                               
 911                 // Update the widget view.                                                               
 912                 PendingAddArguments args = preparePendingAddArgs(requestCode, data, pendingAddWidgetId, m🔵
 913                 if (workspaceLocked) {                                                                   
 914                     sPendingAddItem = args;                                                              
 915                 } else {                                                                                 
 916                     completeAdd(args);                                                                   
 917                 }                                                                                        
 918             }                                                                                            
 919             // Leave the widget in the pending state if the user canceled the configure.                 
 920             return;                                                                                      
 921         }                                                                                                
 922         // The pattern used here is that a user PICKs a specific application,                            
 923         // which, depending on the target, might need to CREATE the actual target.                       
 924         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 925         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 926         if ((resultCode == RESULT_OK) && (mPendingAddInfo.container != ItemInfo.NO_ID)) {                
 927             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1, mPendingAddInfo🔵
 928             if (isWorkspaceLocked()) {                                                                   
 929                 sPendingAddItem = args;                                                                  
 930             } else {                                                                                     
 931                 completeAdd(args);                                                                       
 932                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded, ON_ACTIVITY_RESULT_ANIMA🔵
 933             }                                                                                            
 934         } else if (resultCode == RESULT_CANCELED) {                                                      
 935             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded, ON_ACTIVITY_RESULT_ANIMATION🔵
 936         }                                                                                                
 937         mDragLayer.clearAnimatedView();                                                                  
 938     }                                                                                                    
 939                                                                                                          
 940     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int appWidgetId, Item🔵
 941         PendingAddArguments args = new PendingAddArguments();                                            
 942         args.requestCode = requestCode;                                                                  
 943         args.intent = data;                                                                              
 944         args.container = info.container;                                                                 
 945         args.screenId = info.screenId;                                                                   
 946         args.cellX = info.cellX;                                                                         
 947         args.cellY = info.cellY;                                                                         
 948         args.appWidgetId = appWidgetId;                                                                  
 949         return args;                                                                                     
 950     }                                                                                                    
 951                                                                                                          
 952     /**                                                                                                  
 953      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 954      *                                                                                                   
 955      * @param screenId the screen id to check                                                            
 956      * @return the new screen, or screenId if it exists                                                  
 957      */                                                                                                  
 958     private long ensurePendingDropLayoutExists(long screenId) {                                          
 959         CellLayout dropLayout = ((CellLayout) (mWorkspace.getScreenWithId(screenId)));                   
 960         if (dropLayout == null) {                                                                        
 961             // it's possible that the add screen was removed because it was                              
 962             // empty and a re-bind occurred                                                              
 963             mWorkspace.addExtraEmptyScreen();                                                            
 964             return mWorkspace.commitExtraEmptyScreen();                                                  
 965         } else {                                                                                         
 966             return screenId;                                                                             
 967         }                                                                                                
 968     }                                                                                                    
 969                                                                                                          
 970     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {               
 971         CellLayout cellLayout =                                                                          
 972                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 973         Runnable onCompleteRunnable = null;                                                              
 974         int animationType = 0;                                                                           
 975                                                                                                          
 976         AppWidgetHostView boundWidget = null;                                                            
 977         if (resultCode == RESULT_OK) {                                                                   
 978             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 979             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 980                     mPendingAddWidgetInfo);                                                              
 981             boundWidget = layout;                                                                        
 982             onCompleteRunnable = new Runnable() {                                                        
 983                 @Override                                                                                
 984                 public void run() {                                                                      
 985                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 986                             mPendingAddInfo.screenId, layout, null);                                     
 987                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 988                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 989                 }                                                                                        
 990             };                                                                                           
 991         } else if (resultCode == RESULT_CANCELED) {                                                      
 992             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 993             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 994         }                                                                                                
 995         if (mDragLayer.getAnimatedView() != null) {                                                      
 996             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 997                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 998                     animationType, boundWidget, true);                                                   
 999         } else if (onCompleteRunnable != null) {                                                         
1000             // The animated view may be null in the case of a rotation during widget configuration       
1001             onCompleteRunnable.run();                                                                    
1002         }                                                                                                
1003     }                                                                                                    
1004                                                                                                          
1005     @Override                                                                                            
1006     protected void onStop() {                                                                            
1007         super.onStop();                                                                                  
1008         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1009     }                                                                                                    
1010                                                                                                          
1011     @Override                                                                                            
1012     protected void onStart() {                                                                           
1013         super.onStart();                                                                                 
1014         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1015     }                                                                                                    
1016                                                                                                          
1017     @Override                                                                                            
1018     protected void onResume() {                                                                          
1019         long startTime = 0;                                                                              
1020         if (DEBUG_RESUME_TIME) {                                                                         
1021             startTime = System.currentTimeMillis();                                                      
1022             Log.v(TAG, "Launcher.onResume()");                                                           
1023         }                                                                                                
1024         super.onResume();                                                                                
1025         // Restore the previous launcher state                                                           
1026         if (mOnResumeState == State.WORKSPACE) {                                                         
1027             showWorkspace(false);                                                                        
1028         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                             
1029             showAllApps(false, mAppsCustomizeContent.getContentType(), false);                           
1030         }                                                                                                
1031         mOnResumeState = State.NONE;                                                                     
1032         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1033         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1034         mPaused = false;                                                                                 
1035         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1036             setWorkspaceLoading(true);                                                                   
1037             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1038             mRestoring = false;                                                                          
1039             mOnResumeNeedsLoad = false;                                                                  
1040         }                                                                                                
1041         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1042             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1043             // execute them here                                                                         
1044             long startTimeCallbacks = 0;                                                                 
1045             if (DEBUG_RESUME_TIME) {                                                                     
1046                 startTimeCallbacks = System.currentTimeMillis();                                         
1047             }                                                                                            
1048             if (mAppsCustomizeContent != null) {                                                         
1049                 mAppsCustomizeContent.setBulkBind(true);                                                 
1050             }                                                                                            
1051             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1052                 mBindOnResumeCallbacks.get(i).run();                                                     
1053             }                                                                                            
1054             if (mAppsCustomizeContent != null) {                                                         
1055                 mAppsCustomizeContent.setBulkBind(false);                                                
1056             }                                                                                            
1057             mBindOnResumeCallbacks.clear();                                                              
1058             if (DEBUG_RESUME_TIME) {                                                                     
1059                 Log.d(TAG, "Time spent processing callbacks in onResume: " + (System.currentTimeMillis() 🔵
1060             }                                                                                            
1061         }                                                                                                
1062         if (mOnResumeCallbacks.size() > 0) {                                                             
1063             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1064                 mOnResumeCallbacks.get(i).run();                                                         
1065             }                                                                                            
1066             mOnResumeCallbacks.clear();                                                                  
1067         }                                                                                                
1068         // Reset the pressed state of icons that were locked in the press state while activities         
1069         // were launching                                                                                
1070         if (mWaitingForResume != null) {                                                                 
1071             // Resets the previous workspace icon press state                                            
1072             mWaitingForResume.setStayPressed(false);                                                     
1073         }                                                                                                
1074         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1075         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1076         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1077         // orientation.                                                                                  
1078         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1079         // Process any items that were added while Launcher was away.                                    
1080         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1081         // Update the voice search button proxy                                                          
1082         updateVoiceButtonProxyVisible(false);                                                            
1083         // Again, as with the above scenario, it's possible that one or more of the global icons         
1084         // were updated in the wrong orientation.                                                        
1085         updateGlobalIcons();                                                                             
1086         if (DEBUG_RESUME_TIME) {                                                                         
1087             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1088         }                                                                                                
1089         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1090             // If we are resuming and the custom content is the current page, we call onShow().          
1091             // It is also poassible that onShow will instead be called slightly after first layout       
1092             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1093             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1094                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1095             }                                                                                            
1096         }                                                                                                
1097         mWorkspace.updateInteractionForState();                                                          
1098         mWorkspace.onResume();                                                                           
1099         PackageInstallerCompat.getInstance(this).onResume();                                             
1100     }                                                                                                    
1101                                                                                                          
1102     @Override                                                                                            
1103     protected void onPause() {                                                                           
1104         // Ensure that items added to Launcher are queued until Launcher returns                         
1105         InstallShortcutReceiver.enableInstallQueue();                                                    
1106         PackageInstallerCompat.getInstance(this).onPause();                                              
1107         super.onPause();                                                                                 
1108         mPaused = true;                                                                                  
1109         mDragController.cancelDrag();                                                                    
1110         mDragController.resetLastGestureUpTime();                                                        
1111         // We call onHide() aggressively. The custom content callbacks should be able to                 
1112         // debounce excess onHide calls.                                                                 
1113         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1114             mWorkspace.getCustomContentCallbacks().onHide();                                             
1115         }                                                                                                
1116     }                                                                                                    
1117                                                                                                          
1118     QSBScroller mQsbScroller = new QSBScroller() {                                                       
1119         int scrollY = 0;                                                                                 
1120                                                                                                          
1121         @Override                                                                                        
1122         public void setScrollY(int scroll) {                                                             
1123             scrollY = scroll;                                                                            
1124                                                                                                          
1125             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1126                 mSearchDropTargetBar.setTranslationY(- scrollY);                                         
1127                 getQsbBar().setTranslationY(-scrollY);                                                   
1128             }                                                                                            
1129         }                                                                                                
1130     };                                                                                                   
1131                                                                                                          
1132     public void resetQSBScroll() {                                                                       
1133         mSearchDropTargetBar.animate().translationY(0).start();                                          
1134         getQsbBar().animate().translationY(0).start();                                                   
1135     }                                                                                                    
1136                                                                                                          
1137     public interface CustomContentCallbacks {                                                            
1138         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1139         // by a onResume or by scrolling otherwise.                                                      
1140         public abstract void onShow(boolean fromResume);                                                 
1141                                                                                                          
1142         // Custom content is completely hidden                                                           
1143         public void onHide();                                                                            
1144                                                                                                          
1145         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1146         public void onScrollProgressChanged(float progress);                                             
1147                                                                                                          
1148         // Indicates whether the user is allowed to scroll away from the custom content.                 
1149         boolean isScrollingAllowed();                                                                    
1150     }                                                                                                    
1151                                                                                                          
1152     protected boolean hasSettings() {                                                                    
1153         return false;                                                                                    
1154     }                                                                                                    
1155                                                                                                          
1156     public interface QSBScroller {                                                                       
1157         public abstract void setScrollY(int scrollY);                                                    
1158     }                                                                                                    
1159                                                                                                          
1160     public QSBScroller addToCustomContentPage(View customContent,                                        
1161             CustomContentCallbacks callbacks, String description) {                                      
1162         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1163         return mQsbScroller;                                                                             
1164     }                                                                                                    
1165                                                                                                          
1166     // The custom content needs to offset its content to account for the QSB                             
1167     public int getTopOffsetForCustomContent() {                                                          
1168         return mWorkspace.getPaddingTop();                                                               
1169     }                                                                                                    
1170                                                                                                          
1171     @Override                                                                                            
1172     public Object onRetainNonConfigurationInstance() {                                                   
1173         // Flag the loader to stop early before switching                                                
1174         if (mModel.isCurrentCallbacks(this)) {                                                           
1175             mModel.stopLoader();                                                                         
1176         }                                                                                                
1177         if (mAppsCustomizeContent != null) {                                                             
1178             mAppsCustomizeContent.surrender();                                                           
1179         }                                                                                                
1180         return Boolean.TRUE;                                                                             
1181     }                                                                                                    
1182                                                                                                          
1183     // We can't hide the IME if it was forced open.  So don't bother                                     
1184     @Override                                                                                            
1185     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1186         super.onWindowFocusChanged(hasFocus);                                                            
1187         mHasFocus = hasFocus;                                                                            
1188     }                                                                                                    
1189                                                                                                          
1190     private boolean acceptFilter() {                                                                     
1191         final InputMethodManager inputManager = (InputMethodManager)                                     
1192                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1193         return !inputManager.isFullscreenMode();                                                         
1194     }                                                                                                    
1195                                                                                                          
1196     @Override                                                                                            
1197     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1198         final int uniChar = event.getUnicodeChar();                                                      
1199         final boolean handled = super.onKeyDown(keyCode, event);                                         
1200         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1201         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1202             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1203                     keyCode, event);                                                                     
1204             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1205                 // something usable has been typed - start a search                                      
1206                 // the typed text will be retrieved and cleared by                                       
1207                 // showSearchDialog()                                                                    
1208                 // If there are multiple keystrokes before the search dialog takes focus,                
1209                 // onSearchRequested() will be called for every keystroke,                               
1210                 // but it is idempotent, so it's fine.                                                   
1211                 return onSearchRequested();                                                              
1212             }                                                                                            
1213         }                                                                                                
1214                                                                                                          
1215         // Eat the long press event so the keyboard doesn't come up.                                     
1216         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1217             return true;                                                                                 
1218         }                                                                                                
1219                                                                                                          
1220         return handled;                                                                                  
1221     }                                                                                                    
1222                                                                                                          
1223     private String getTypedText() {                                                                      
1224         return mDefaultKeySsb.toString();                                                                
1225     }                                                                                                    
1226                                                                                                          
1227     private void clearTypedText() {                                                                      
1228         mDefaultKeySsb.clear();                                                                          
1229         mDefaultKeySsb.clearSpans();                                                                     
1230         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1231     }                                                                                                    
1232                                                                                                          
1233     /**                                                                                                  
1234      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1235      * State                                                                                             
1236      */                                                                                                  
1237     private static State intToState(int stateOrdinal) {                                                  
1238         State state = State.WORKSPACE;                                                                   
1239         final State[] stateValues = State.values();                                                      
1240         for (int i = 0; i < stateValues.length; i++) {                                                   
1241             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1242                 state = stateValues[i];                                                                  
1243                 break;                                                                                   
1244             }                                                                                            
1245         }                                                                                                
1246         return state;                                                                                    
1247     }                                                                                                    
1248                                                                                                          
1249     /**                                                                                                  
1250      * Restores the previous state, if it exists.                                                        
1251      *                                                                                                   
1252      * @param savedState The previous state.                                                             
1253      */                                                                                                  
1254     @SuppressWarnings("unchecked")                                                                       
1255     private void restoreState(Bundle savedState) {                                                       
1256         if (savedState == null) {                                                                        
1257             return;                                                                                      
1258         }                                                                                                
1259         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1260         if (state == State.APPS_CUSTOMIZE) {                                                             
1261             mOnResumeState = State.APPS_CUSTOMIZE;                                                       
1262         }                                                                                                
1263         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, PagedView.INVALID_RESTORE_PAG🔵
1264         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1265             mWorkspace.setRestorePage(currentScreen);                                                    
1266         }                                                                                                
1267         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1268         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1269         if ((pendingAddContainer != ItemInfo.NO_ID) && (pendingAddScreen > (-1))) {                      
1270             mPendingAddInfo.container = pendingAddContainer;                                             
1271             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1272             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1273             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1274             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1275             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1276             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);     
1277             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1278             setWaitingForResult(true);                                                                   
1279             mRestoring = true;                                                                           
1280         }                                                                                                
1281         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1282         if (renameFolder) {                                                                              
1283             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1284             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1285             mRestoring = true;                                                                           
1286         }                                                                                                
1287         // Restore the AppsCustomize tab                                                                 
1288         if (mAppsCustomizeTabHost != null) {                                                             
1289             String curTab = savedState.getString("apps_customize_currentTab");                           
1290             if (curTab != null) {                                                                        
1291                 mAppsCustomizeTabHost.setContentTypeImmediate(mAppsCustomizeTabHost.getContentTypeForTabT🔵
1292                 mAppsCustomizeContent.loadAssociatedPages(mAppsCustomizeContent.getCurrentPage());       
1293             }                                                                                            
1294             int currentIndex = savedState.getInt("apps_customize_currentIndex");                         
1295             mAppsCustomizeContent.restorePageForIndex(currentIndex);                                     
1296         }                                                                                                
1297         mItemIdToViewId = ((HashMap<Integer, Integer>) (savedState.getSerializable(RUNTIME_STATE_VIEW_IDS🔵
1298     }                                                                                                    
1299                                                                                                          
1300     /**                                                                                                  
1301      * Finds all the views we need and configure them properly.                                          
1302      */                                                                                                  
1303     private void setupViews() {                                                                          
1304         final DragController dragController = mDragController;                                           
1305         mLauncherView = findViewById(R.id.launcher);                                                     
1306         mFocusHandler = ((FocusIndicatorView) (findViewById(R.id.focus_indicator)));                     
1307         mDragLayer = ((DragLayer) (findViewById(R.id.drag_layer)));                                      
1308         mWorkspace = ((Workspace) (mDragLayer.findViewById(R.id.workspace)));                            
1309         mWorkspace.setPageSwitchListener(this);                                                          
1310         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1311         mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_L🔵
1312         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1313         // Setup the drag layer                                                                          
1314         mDragLayer.setup(this, dragController);                                                          
1315         // Setup the hotseat                                                                             
1316         mHotseat = ((Hotseat) (findViewById(R.id.hotseat)));                                             
1317         if (mHotseat != null) {                                                                          
1318             mHotseat.setup(this);                                                                        
1319             mHotseat.setOnLongClickListener(this);                                                       
1320         }                                                                                                
1321         mOverviewPanel = ((ViewGroup) (findViewById(R.id.overview_panel)));                              
1322         View widgetButton = findViewById(R.id.widget_button);                                            
1323         widgetButton.setOnClickListener(new OnClickListener() {                                          
1324             @Override                                                                                    
1325             public void onClick(View arg0) {                                                             
1326                 if (!mWorkspace.isSwitchingState()) {                                                    
1327                     onClickAddWidgetButton(arg0);                                                        
1328                 }                                                                                        
1329             }                                                                                            
1330         });                                                                                              
1331         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1332         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1333         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1334             @Override                                                                                    
1335             public void onClick(View arg0) {                                                             
1336                 if (!mWorkspace.isSwitchingState()) {                                                    
1337                     onClickWallpaperPicker(arg0);                                                        
1338                 }                                                                                        
1339             }                                                                                            
1340         });                                                                                              
1341         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1342         View settingsButton = findViewById(R.id.settings_button);                                        
1343         if (hasSettings()) {                                                                             
1344             settingsButton.setOnClickListener(new OnClickListener() {                                    
1345                 @Override                                                                                
1346                 public void onClick(View arg0) {                                                         
1347                     if (!mWorkspace.isSwitchingState()) {                                                
1348                         onClickSettingsButton(arg0);                                                     
1349                     }                                                                                    
1350                 }                                                                                        
1351             });                                                                                          
1352             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1353         } else {                                                                                         
1354             settingsButton.setVisibility(View.GONE);                                                     
1355             FrameLayout.LayoutParams lp = ((FrameLayout.LayoutParams) (widgetButton.getLayoutParams())); 
1356             lp.gravity = Gravity.END | Gravity.TOP;                                                      
1357             widgetButton.requestLayout();                                                                
1358         }                                                                                                
1359         mOverviewPanel.setAlpha(0.0F);                                                                   
1360         // Setup the workspace                                                                           
1361         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1362         mWorkspace.setOnLongClickListener(this);                                                         
1363         mWorkspace.setup(dragController);                                                                
1364         dragController.addDragListener(mWorkspace);                                                      
1365         // Get the search/delete bar                                                                     
1366         mSearchDropTargetBar = ((SearchDropTargetBar) (mDragLayer.findViewById(R.id.search_drop_target_ba🔵
1367         // Setup AppsCustomize                                                                           
1368         mAppsCustomizeTabHost = ((AppsCustomizeTabHost) (findViewById(R.id.apps_customize_pane)));       
1369         mAppsCustomizeContent = ((AppsCustomizePagedView) (mAppsCustomizeTabHost.findViewById(R.id.apps_c🔵
1370         mAppsCustomizeContent.setup(this, dragController);                                               
1371         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1372         dragController.setDragScoller(mWorkspace);                                                       
1373         dragController.setScrollView(mDragLayer);                                                        
1374         dragController.setMoveTarget(mWorkspace);                                                        
1375         dragController.addDropTarget(mWorkspace);                                                        
1376         if (mSearchDropTargetBar != null) {                                                              
1377             mSearchDropTargetBar.setup(this, dragController);                                            
1378         }                                                                                                
1379         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1380             Log.v(TAG, "adding WeightWatcher");                                                          
1381             mWeightWatcher = new WeightWatcher(this);                                                    
1382             mWeightWatcher.setAlpha(0.5F);                                                               
1383             ((FrameLayout) (mLauncherView)).addView(mWeightWatcher, new FrameLayout.LayoutParams(FrameLay🔵
1384             boolean show = shouldShowWeightWatcher();                                                    
1385             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1386         }                                                                                                
1387     }                                                                                                    
1388                                                                                                          
1389     /**                                                                                                  
1390      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1391      */                                                                                                  
1392     public void setAllAppsButton(View allAppsButton) {                                                   
1393         mAllAppsButton = allAppsButton;                                                                  
1394     }                                                                                                    
1395                                                                                                          
1396     public View getAllAppsButton() {                                                                     
1397         return mAllAppsButton;                                                                           
1398     }                                                                                                    
1399                                                                                                          
1400     /**                                                                                                  
1401      * Creates a view representing a shortcut.                                                           
1402      *                                                                                                   
1403      * @param info The data structure describing the shortcut.                                           
1404      *                                                                                                   
1405      * @return A View inflated from R.layout.application.                                                
1406      */                                                                                                  
1407     View createShortcut(ShortcutInfo info) {                                                             
1408         return createShortcut(R.layout.application,                                                      
1409                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1410     }                                                                                                    
1411                                                                                                          
1412     /**                                                                                                  
1413      * Creates a view representing a shortcut inflated from the specified resource.                      
1414      *                                                                                                   
1415      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1416      * @param parent The group the shortcut belongs to.                                                  
1417      * @param info The data structure describing the shortcut.                                           
1418      *                                                                                                   
1419      * @return A View inflated from layoutResId.                                                         
1420      */                                                                                                  
1421     View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                          
1422         BubbleTextView favorite = ((BubbleTextView) (mInflater.inflate(layoutResId, parent, false)));    
1423         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1424         favorite.setOnClickListener(this);                                                               
1425         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1426         return favorite;                                                                                 
1427     }                                                                                                    
1428                                                                                                          
1429     /**                                                                                                  
1430      * Add a shortcut to the workspace.                                                                  
1431      *                                                                                                   
1432      * @param data The intent describing the shortcut.                                                   
1433      * @param cellInfo The position on screen where to create the shortcut.                              
1434      */                                                                                                  
1435     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1436             int cellY) {                                                                                 
1437         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1438         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1439         CellLayout layout = getCellLayout(container, screenId);                                          
1440                                                                                                          
1441         boolean foundCellSpan = false;                                                                   
1442                                                                                                          
1443         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                             
1444         if (info == null) {                                                                              
1445             return;                                                                                      
1446         }                                                                                                
1447         final View view = createShortcut(info);                                                          
1448                                                                                                          
1449         // First we check if we already know the exact location where we want to add this item.          
1450         if (cellX >= 0 && cellY >= 0) {                                                                  
1451             cellXY[0] = cellX;                                                                           
1452             cellXY[1] = cellY;                                                                           
1453             foundCellSpan = true;                                                                        
1454                                                                                                          
1455             // If appropriate, either create a folder or add to an existing folder                       
1456             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1457                     true, null,null)) {                                                                  
1458                 return;                                                                                  
1459             }                                                                                            
1460             DragObject dragObject = new DragObject();                                                    
1461             dragObject.dragInfo = info;                                                                  
1462             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1463                     true)) {                                                                             
1464                 return;                                                                                  
1465             }                                                                                            
1466         } else if (touchXY != null) {                                                                    
1467             // when dragging and dropping, just find the closest free spot                               
1468             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1469             foundCellSpan = (result != null);                                                            
1470         } else {                                                                                         
1471             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1472         }                                                                                                
1473                                                                                                          
1474         if (!foundCellSpan) {                                                                            
1475             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1476             return;                                                                                      
1477         }                                                                                                
1478                                                                                                          
1479         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);   
1480                                                                                                          
1481         if (!mRestoring) {                                                                               
1482             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1483                     isWorkspaceLocked());                                                                
1484         }                                                                                                
1485     }                                                                                                    
1486                                                                                                          
1487     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1488             int minHeight) {                                                                             
1489         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1490         // We want to account for the extra amount of padding that we are adding to the widget           
1491         // to ensure that it gets the full amount of space that it has requested                         
1492         int requiredWidth = minWidth + padding.left + padding.right;                                     
1493         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1494         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1495     }                                                                                                    
1496                                                                                                          
1497     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1498         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1499     }                                                                                                    
1500                                                                                                          
1501     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1502         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1503     }                                                                                                    
1504                                                                                                          
1505     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1506         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1507     }                                                                                                    
1508                                                                                                          
1509     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1510         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1511                 info.minResizeHeight);                                                                   
1512     }                                                                                                    
1513                                                                                                          
1514     /**                                                                                                  
1515      * Add a widget to the workspace.                                                                    
1516      *                                                                                                   
1517      * @param appWidgetId The app widget id                                                              
1518      * @param cellInfo The position on screen where to create the widget.                                
1519      */                                                                                                  
1520     private void completeAddAppWidget(final int appWidgetId, long container, long screenId, AppWidgetHost🔵
1521         if (appWidgetInfo == null) {                                                                     
1522             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
1523         }                                                                                                
1524         // Calculate the grid spans needed to fit this widget                                            
1525         CellLayout layout = getCellLayout(container, screenId);                                          
1526         int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                      
1527         int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                            
1528         // Try finding open space on Launcher screen                                                     
1529         // We have saved the position to which the widget was dragged-- this really only matters         
1530         // if we are placing widgets on a "spring-loaded" screen                                         
1531         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1532         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1533         int[] finalSpan = new int[2];                                                                    
1534         boolean foundCellSpan = false;                                                                   
1535         if ((mPendingAddInfo.cellX >= 0) && (mPendingAddInfo.cellY >= 0)) {                              
1536             cellXY[0] = mPendingAddInfo.cellX;                                                           
1537             cellXY[1] = mPendingAddInfo.cellY;                                                           
1538             spanXY[0] = mPendingAddInfo.spanX;                                                           
1539             spanXY[1] = mPendingAddInfo.spanY;                                                           
1540             foundCellSpan = true;                                                                        
1541         } else if (touchXY != null) {                                                                    
1542             // when dragging and dropping, just find the closest free spot                               
1543             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1🔵
1544             spanXY[0] = finalSpan[0];                                                                    
1545             spanXY[1] = finalSpan[1];                                                                    
1546             foundCellSpan = result != null;                                                              
1547         } else {                                                                                         
1548             foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                  
1549         }                                                                                                
1550         if (!foundCellSpan) {                                                                            
1551             if (appWidgetId != (-1)) {                                                                   
1552                 // Deleting an app widget ID is a void call but writes to disk before returning          
1553                 // to the caller...                                                                      
1554                 new AsyncTask<Void, Void, Void>() {                                                      
1555                     public Void doInBackground(Void... args) {                                           
1556                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                   
1557                         return null;                                                                     
1558                     }                                                                                    
1559                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) (null)));                    
1560             }                                                                                            
1561             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1562             return;                                                                                      
1563         }                                                                                                
1564         // Build Launcher-specific widget info and save to database                                      
1565         LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provide🔵
1566         launcherInfo.spanX = spanXY[0];                                                                  
1567         launcherInfo.spanY = spanXY[1];                                                                  
1568         launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                
1569         launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                
1570         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1571         LauncherModel.addItemToDatabase(this, launcherInfo, container, screenId, cellXY[0], cellXY[1], fa🔵
1572         if (!mRestoring) {                                                                               
1573             if (hostView == null) {                                                                      
1574                 // Perform actual inflation because we're live                                           
1575                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1576                 launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                          
1577             } else {                                                                                     
1578                 // The AppWidgetHostView has already been inflated and instantiated                      
1579                 launcherInfo.hostView = hostView;                                                        
1580             }                                                                                            
1581             launcherInfo.hostView.setTag(launcherInfo);                                                  
1582             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1583             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1584             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1], laun🔵
1585             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1586         }                                                                                                
1587         resetAddInfo();                                                                                  
1588     }                                                                                                    
1589                                                                                                          
1590     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1591         @Override                                                                                        
1592         public void onReceive(Context context, Intent intent) {                                          
1593             final String action = intent.getAction();                                                    
1594             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1595                 mUserPresent = false;                                                                    
1596                 mDragLayer.clearAllResizeFrames();                                                       
1597                 updateRunning();                                                                         
1598                 // Reset AllApps to its initial state only if we are not in the middle of                
1599                 // processing a multi-step drop                                                          
1600                 if ((mAppsCustomizeTabHost != null) && (mPendingAddInfo.container == ItemInfo.NO_ID)) {  
1601                     showWorkspace(false);                                                                
1602                 }                                                                                        
1603             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1604                 mUserPresent = true;                                                                     
1605                 updateRunning();                                                                         
1606             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1607                 mModel.resetLoadedState(false, true);                                                    
1608                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1609             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1610                 mModel.resetLoadedState(false, true);                                                    
1611                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1612             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action) || LauncherAppsComp🔵
1613                 getModel().forceReload();                                                                
1614             }                                                                                            
1615         }                                                                                                
1616     };                                                                                                   
1617                                                                                                          
1618     @Override                                                                                            
1619     public void onAttachedToWindow() {                                                                   
1620         super.onAttachedToWindow();                                                                      
1621         // Listen for broadcasts related to user-presence                                                
1622         final IntentFilter filter = new IntentFilter();                                                  
1623         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1624         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1625         // For handling managed profiles                                                                 
1626         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1627         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1628         if (ENABLE_DEBUG_INTENTS) {                                                                      
1629             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1630             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1631         }                                                                                                
1632         registerReceiver(mReceiver, filter);                                                             
1633         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1634         setupTransparentSystemBarsForLmp();                                                              
1635         mAttached = true;                                                                                
1636         mVisible = true;                                                                                 
1637     }                                                                                                    
1638                                                                                                          
1639     /**                                                                                                  
1640      * Sets up transparent navigation and status bars in LMP.                                            
1641      * This method is a no-op for other platform versions.                                               
1642      */                                                                                                  
1643     @TargetApi(19)                                                                                       
1644     private void setupTransparentSystemBarsForLmp() {                                                    
1645         // TODO(sansid): use the APIs directly when compiling against L sdk.                             
1646         // Currently we use reflection to access the flags and the API to set the transparency           
1647         // on the System bars.                                                                           
1648         if (Utilities.isLmpOrAbove()) {                                                                  
1649             try {                                                                                        
1650                 getWindow().getAttributes().systemUiVisibility |=                                        
1651                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1652                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1653                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1654                 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                
1655                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1656                 Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(              
1657                         "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                            
1658                 getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                             
1659                                                                                                          
1660                 Method setStatusBarColorMethod =                                                         
1661                         Window.class.getDeclaredMethod("setStatusBarColor", int.class);                  
1662                 Method setNavigationBarColorMethod =                                                     
1663                         Window.class.getDeclaredMethod("setNavigationBarColor", int.class);              
1664                 setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                          
1665                 setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                      
1666             } catch (NoSuchFieldException e) {                                                           
1667                 Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                    
1668             } catch (NoSuchMethodException ex) {                                                         
1669                 Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                   
1670             } catch (IllegalAccessException e) {                                                         
1671                 Log.w(TAG, "IllegalAccessException while setting up transparent bars");                  
1672             } catch (IllegalArgumentException e) {                                                       
1673                 Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                
1674             } catch (InvocationTargetException e) {                                                      
1675                 Log.w(TAG, "InvocationTargetException while setting up transparent bars");               
1676             } finally {}                                                                                 
1677         }                                                                                                
1678     }                                                                                                    
1679                                                                                                          
1680     @Override                                                                                            
1681     public void onDetachedFromWindow() {                                                                 
1682         super.onDetachedFromWindow();                                                                    
1683         mVisible = false;                                                                                
1684                                                                                                          
1685         if (mAttached) {                                                                                 
1686             unregisterReceiver(mReceiver);                                                               
1687             mAttached = false;                                                                           
1688         }                                                                                                
1689         updateRunning();                                                                                 
1690     }                                                                                                    
1691                                                                                                          
1692     public void onWindowVisibilityChanged(int visibility) {                                              
1693         mVisible = visibility == View.VISIBLE;                                                           
1694         updateRunning();                                                                                 
1695         // The following code used to be in onResume, but it turns out onResume is called when           
1696         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1697         // is a more appropriate event to handle                                                         
1698         if (mVisible) {                                                                                  
1699             mAppsCustomizeTabHost.onWindowVisible();                                                     
1700             if (!mWorkspaceLoading) {                                                                    
1701                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1702                 // We want to let Launcher draw itself at least once before we force it to build         
1703                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1704                 // apps is nice and speedy.                                                              
1705                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1706                     private boolean mStarted = false;                                                    
1707                                                                                                          
1708                     public void onDraw() {                                                               
1709                         if (mStarted) {                                                                  
1710                             return;                                                                      
1711                         }                                                                                
1712                         mStarted = true;                                                                 
1713                         // We delay the layer building a bit in order to give                            
1714                         // other message processing a time to run.  In particular                        
1715                         // this avoids a delay in hiding the IME if it was                               
1716                         // currently shown, because doing that may involve                               
1717                         // some communication back with the app.                                         
1718                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1719                         final ViewTreeObserver.OnDrawListener listener = this;                           
1720                         mWorkspace.post(new Runnable() {                                                 
1721                             public void run() {                                                          
1722                                 if ((mWorkspace != null) && (mWorkspace.getViewTreeObserver() != null)) {
1723                                     mWorkspace.getViewTreeObserver().removeOnDrawListener(listener);     
1724                                 }                                                                        
1725                             }                                                                            
1726                         });                                                                              
1727                         return;                                                                          
1728                     }                                                                                    
1729                 });                                                                                      
1730             }                                                                                            
1731             clearTypedText();                                                                            
1732         }                                                                                                
1733     }                                                                                                    
1734                                                                                                          
1735     private void sendAdvanceMessage(long delay) {                                                        
1736         mHandler.removeMessages(ADVANCE_MSG);                                                            
1737         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1738         mHandler.sendMessageDelayed(msg, delay);                                                         
1739         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1740     }                                                                                                    
1741                                                                                                          
1742     private void updateRunning() {                                                                       
1743         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1744         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1745             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1746             if (autoAdvanceRunning) {                                                                    
1747                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1748                 sendAdvanceMessage(delay);                                                               
1749             } else {                                                                                     
1750                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1751                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1752                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1753                 }                                                                                        
1754                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1755                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1756             }                                                                                            
1757         }                                                                                                
1758     }                                                                                                    
1759                                                                                                          
1760     private final Handler mHandler = new Handler() {                                                     
1761         @Override                                                                                        
1762         public void handleMessage(Message msg) {                                                         
1763             if (msg.what == ADVANCE_MSG) {                                                               
1764                 int i = 0;                                                                               
1765                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1766                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1767                     final int delay = mAdvanceStagger * i;                                               
1768                     if (v instanceof Advanceable) {                                                      
1769                        postDelayed(new Runnable() {                                                      
1770                            public void run() {                                                           
1771                                ((Advanceable) v).advance();                                              
1772                            }                                                                             
1773                        }, delay);                                                                        
1774                     }                                                                                    
1775                     i++;                                                                                 
1776                 }                                                                                        
1777                 sendAdvanceMessage(mAdvanceInterval);                                                    
1778             }                                                                                            
1779         }                                                                                                
1780     };                                                                                                   
1781                                                                                                          
1782     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1783         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1784         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1785         if (v instanceof Advanceable) {                                                                  
1786             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1787             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1788             updateRunning();                                                                             
1789         }                                                                                                
1790     }                                                                                                    
1791                                                                                                          
1792     void removeWidgetToAutoAdvance(View hostView) {                                                      
1793         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1794             mWidgetsToAdvance.remove(hostView);                                                          
1795             updateRunning();                                                                             
1796         }                                                                                                
1797     }                                                                                                    
1798                                                                                                          
1799     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1800         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1801         launcherInfo.hostView = null;                                                                    
1802     }                                                                                                    
1803                                                                                                          
1804     void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                
1805         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1806         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1807     }                                                                                                    
1808                                                                                                          
1809     public DragLayer getDragLayer() {                                                                    
1810         return mDragLayer;                                                                               
1811     }                                                                                                    
1812                                                                                                          
1813     public Workspace getWorkspace() {                                                                    
1814         return mWorkspace;                                                                               
1815     }                                                                                                    
1816                                                                                                          
1817     public Hotseat getHotseat() {                                                                        
1818         return mHotseat;                                                                                 
1819     }                                                                                                    
1820                                                                                                          
1821     public ViewGroup getOverviewPanel() {                                                                
1822         return mOverviewPanel;                                                                           
1823     }                                                                                                    
1824                                                                                                          
1825     public SearchDropTargetBar getSearchBar() {                                                          
1826         return mSearchDropTargetBar;                                                                     
1827     }                                                                                                    
1828                                                                                                          
1829     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1830         return mAppWidgetHost;                                                                           
1831     }                                                                                                    
1832                                                                                                          
1833     public LauncherModel getModel() {                                                                    
1834         return mModel;                                                                                   
1835     }                                                                                                    
1836                                                                                                          
1837     protected SharedPreferences getSharedPrefs() {                                                       
1838         return mSharedPrefs;                                                                             
1839     }                                                                                                    
1840                                                                                                          
1841     public void closeSystemDialogs() {                                                                   
1842         getWindow().closeAllPanels();                                                                    
1843         // Whatever we were doing is hereby canceled.                                                    
1844         setWaitingForResult(false);                                                                      
1845     }                                                                                                    
1846                                                                                                          
1847     @Override                                                                                            
1848     protected void onNewIntent(Intent intent) {                                                          
1849         long startTime = 0;                                                                              
1850         if (DEBUG_RESUME_TIME) {                                                                         
1851             startTime = System.currentTimeMillis();                                                      
1852         }                                                                                                
1853         super.onNewIntent(intent);                                                                       
1854                                                                                                          
1855         // Close the menu                                                                                
1856         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1857             // also will cancel mWaitingForResult.                                                       
1858             closeSystemDialogs();                                                                        
1859                                                                                                          
1860             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1861                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1862                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1863                                                                                                          
1864             if (mWorkspace == null) {                                                                    
1865                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1866                 return;                                                                                  
1867             }                                                                                            
1868             Folder openFolder = mWorkspace.getOpenFolder();                                              
1869             // In all these cases, only animate if we're already on home                                 
1870             mWorkspace.exitWidgetResizeMode();                                                           
1871             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1872                     openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                     
1873                 mWorkspace.moveToDefaultScreen(true);                                                    
1874             }                                                                                            
1875                                                                                                          
1876             closeFolder();                                                                               
1877             exitSpringLoadedDragMode();                                                                  
1878                                                                                                          
1879             // If we are already on home, then just animate back to the workspace,                       
1880             // otherwise, just wait until onResume to set the state back to Workspace                    
1881             if (alreadyOnHome) {                                                                         
1882                 showWorkspace(true);                                                                     
1883             } else {                                                                                     
1884                 mOnResumeState = State.WORKSPACE;                                                        
1885             }                                                                                            
1886                                                                                                          
1887             final View v = getWindow().peekDecorView();                                                  
1888             if (v != null && v.getWindowToken() != null) {                                               
1889                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1890                         INPUT_METHOD_SERVICE);                                                           
1891                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1892             }                                                                                            
1893                                                                                                          
1894             // Reset the apps customize page                                                             
1895             if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                       
1896                 mAppsCustomizeTabHost.reset();                                                           
1897             }                                                                                            
1898                                                                                                          
1899             onHomeIntent();                                                                              
1900         }                                                                                                
1901                                                                                                          
1902         if (DEBUG_RESUME_TIME) {                                                                         
1903             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1904         }                                                                                                
1905     }                                                                                                    
1906                                                                                                          
1907     /**                                                                                                  
1908      * Override point for subclasses to prevent movement to the default screen when the home             
1909      * button is pressed. Used (for example) in GEL, to prevent movement during a search.                
1910      */                                                                                                  
1911     protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                          
1912         return true;                                                                                     
1913     }                                                                                                    
1914                                                                                                          
1915     /**                                                                                                  
1916      * Override point for subclasses to provide custom behaviour for when a home intent is fired.        
1917      */                                                                                                  
1918     protected void onHomeIntent() {                                                                      
1919         // Do nothing                                                                                    
1920     }                                                                                                    
1921                                                                                                          
1922     @Override                                                                                            
1923     public void onRestoreInstanceState(Bundle state) {                                                   
1924         super.onRestoreInstanceState(state);                                                             
1925         for (int page: mSynchronouslyBoundPages) {                                                       
1926             mWorkspace.restoreInstanceStateForChild(page);                                               
1927         }                                                                                                
1928     }                                                                                                    
1929                                                                                                          
1930     @Override                                                                                            
1931     protected void onSaveInstanceState(Bundle outState) {                                                
1932         if (mWorkspace.getChildCount() > 0) {                                                            
1933             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1934                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1935         }                                                                                                
1936         super.onSaveInstanceState(outState);                                                             
1937                                                                                                          
1938         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1939         // We close any open folder since it will not be re-opened, and we need to make sure             
1940         // this state is reflected.                                                                      
1941         closeFolder();                                                                                   
1942                                                                                                          
1943         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1944                 mWaitingForResult) {                                                                     
1945             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1946             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1947             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1948             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1949             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1950             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1951             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1952             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1953         }                                                                                                
1954                                                                                                          
1955         if (mFolderInfo != null && mWaitingForResult) {                                                  
1956             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
1957             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
1958         }                                                                                                
1959                                                                                                          
1960         // Save the current AppsCustomize tab                                                            
1961         if (mAppsCustomizeTabHost != null) {                                                             
1962             AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();            
1963             String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                  
1964             if (currentTabTag != null) {                                                                 
1965                 outState.putString("apps_customize_currentTab", currentTabTag);                          
1966             }                                                                                            
1967             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                        
1968             outState.putInt("apps_customize_currentIndex", currentIndex);                                
1969         }                                                                                                
1970         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1971     }                                                                                                    
1972                                                                                                          
1973     @Override                                                                                            
1974     public void onDestroy() {                                                                            
1975         super.onDestroy();                                                                               
1976         // Remove all pending runnables                                                                  
1977         mHandler.removeMessages(ADVANCE_MSG);                                                            
1978         mHandler.removeMessages(0);                                                                      
1979         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
1980         // Stop callbacks from LauncherModel                                                             
1981         LauncherAppState app = LauncherAppState.getInstance();                                           
1982         // It's possible to receive onDestroy after a new Launcher activity has                          
1983         // been created. In this case, don't interfere with the new Launcher.                            
1984         if (mModel.isCurrentCallbacks(this)) {                                                           
1985             mModel.stopLoader();                                                                         
1986             app.setLauncher(null);                                                                       
1987         }                                                                                                
1988         try {                                                                                            
1989             mAppWidgetHost.stopListening();                                                              
1990         } catch (java.lang.NullPointerException ex) {                                                    
1991             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
1992         }                                                                                                
1993         mAppWidgetHost = null;                                                                           
1994         mWidgetsToAdvance.clear();                                                                       
1995         TextKeyListener.getInstance().release();                                                         
1996         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
1997         // to prevent leaking Launcher activities on orientation change.                                 
1998         if (mModel != null) {                                                                            
1999             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2000         }                                                                                                
2001         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2002         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2003         mDragLayer.clearAllResizeFrames();                                                               
2004         ((ViewGroup) (mWorkspace.getParent())).removeAllViews();                                         
2005         mWorkspace.removeAllWorkspaceScreens();                                                          
2006         mWorkspace = null;                                                                               
2007         mDragController = null;                                                                          
2008         PackageInstallerCompat.getInstance(this).onStop();                                               
2009         LauncherAnimUtils.onDestroyActivity();                                                           
2010     }                                                                                                    
2011                                                                                                          
2012     public DragController getDragController() {                                                          
2013         return mDragController;                                                                          
2014     }                                                                                                    
2015                                                                                                          
2016     @Override                                                                                            
2017     public void startActivityForResult(Intent intent, int requestCode) {                                 
2018         if (requestCode >= 0) {                                                                          
2019             setWaitingForResult(true);                                                                   
2020         }                                                                                                
2021         super.startActivityForResult(intent, requestCode);                                               
2022     }                                                                                                    
2023                                                                                                          
2024     /**                                                                                                  
2025      * Indicates that we want global search for this activity by setting the globalSearch                
2026      * argument for {@link #startSearch} to true.                                                        
2027      */                                                                                                  
2028     @Override                                                                                            
2029     public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData, boolea🔵
2030         showWorkspace(true);                                                                             
2031         if (initialQuery == null) {                                                                      
2032             // Use any text typed in the launcher as the initial query                                   
2033             initialQuery = getTypedText();                                                               
2034         }                                                                                                
2035         if (appSearchData == null) {                                                                     
2036             appSearchData = new Bundle();                                                                
2037             appSearchData.putString("source", "launcher-search");                                        
2038         }                                                                                                
2039         Rect sourceBounds = new Rect();                                                                  
2040         if (mSearchDropTargetBar != null) {                                                              
2041             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2042         }                                                                                                
2043         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery, appSearchData, sourc🔵
2044         if (clearTextImmediately) {                                                                      
2045             clearTypedText();                                                                            
2046         }                                                                                                
2047     }                                                                                                    
2048                                                                                                          
2049     /**                                                                                                  
2050      * Start a text search.                                                                              
2051      *                                                                                                   
2052      * @return {@code true} if the search will start immediately, so any further keypresses              
2053      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2054      * to buffer keypresses.                                                                             
2055      */                                                                                                  
2056     public boolean startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData, Rec🔵
2057         startGlobalSearch(initialQuery, selectInitialQuery, appSearchData, sourceBounds);                
2058         return false;                                                                                    
2059     }                                                                                                    
2060                                                                                                          
2061     /**                                                                                                  
2062      * Starts the global search activity. This code is a copied from SearchManager                       
2063      */                                                                                                  
2064     private void startGlobalSearch(String initialQuery,                                                  
2065             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2066         final SearchManager searchManager =                                                              
2067             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2068         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2069         if (globalSearchActivity == null) {                                                              
2070             Log.w(TAG, "No global search activity found.");                                              
2071             return;                                                                                      
2072         }                                                                                                
2073         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2074         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2075         intent.setComponent(globalSearchActivity);                                                       
2076         // Make sure that we have a Bundle to put source in                                              
2077         if (appSearchData == null) {                                                                     
2078             appSearchData = new Bundle();                                                                
2079         } else {                                                                                         
2080             appSearchData = new Bundle(appSearchData);                                                   
2081         }                                                                                                
2082         // Set source to package name of app that starts global search, if not set already.              
2083         if (!appSearchData.containsKey("source")) {                                                      
2084             appSearchData.putString("source", getPackageName());                                         
2085         }                                                                                                
2086         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2087         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2088             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2089         }                                                                                                
2090         if (selectInitialQuery) {                                                                        
2091             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2092         }                                                                                                
2093         intent.setSourceBounds(sourceBounds);                                                            
2094         try {                                                                                            
2095             startActivity(intent);                                                                       
2096         } catch (ActivityNotFoundException ex) {                                                         
2097             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2098         }                                                                                                
2099     }                                                                                                    
2100                                                                                                          
2101     public boolean isOnCustomContent() {                                                                 
2102         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2103     }                                                                                                    
2104                                                                                                          
2105     @Override                                                                                            
2106     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2107         super.onPrepareOptionsMenu(menu);                                                                
2108         if (!isOnCustomContent()) {                                                                      
2109             // Close any open folders                                                                    
2110             closeFolder();                                                                               
2111             // Stop resizing any widgets                                                                 
2112             mWorkspace.exitWidgetResizeMode();                                                           
2113             if (!mWorkspace.isInOverviewMode()) {                                                        
2114                 // Show the overview mode                                                                
2115                 showOverviewMode(true);                                                                  
2116             } else {                                                                                     
2117                 showWorkspace(true);                                                                     
2118             }                                                                                            
2119         }                                                                                                
2120         return false;                                                                                    
2121     }                                                                                                    
2122                                                                                                          
2123     @Override                                                                                            
2124     public boolean onSearchRequested() {                                                                 
2125         startSearch(null, false, null, true);                                                            
2126         // Use a custom animation for launching search                                                   
2127         return true;                                                                                     
2128     }                                                                                                    
2129                                                                                                          
2130     public boolean isWorkspaceLocked() {                                                                 
2131         return mWorkspaceLoading || mWaitingForResult;                                                   
2132     }                                                                                                    
2133                                                                                                          
2134     public boolean isWorkspaceLoading() {                                                                
2135         return mWorkspaceLoading;                                                                        
2136     }                                                                                                    
2137                                                                                                          
2138     private void setWorkspaceLoading(boolean value) {                                                    
2139         boolean isLocked = isWorkspaceLocked();                                                          
2140         mWorkspaceLoading = value;                                                                       
2141         if (isLocked != isWorkspaceLocked()) {                                                           
2142             onWorkspaceLockedChanged();                                                                  
2143         }                                                                                                
2144     }                                                                                                    
2145                                                                                                          
2146     private void setWaitingForResult(boolean value) {                                                    
2147         boolean isLocked = isWorkspaceLocked();                                                          
2148         mWaitingForResult = value;                                                                       
2149         if (isLocked != isWorkspaceLocked()) {                                                           
2150             onWorkspaceLockedChanged();                                                                  
2151         }                                                                                                
2152     }                                                                                                    
2153                                                                                                          
2154     protected void onWorkspaceLockedChanged() {                                                          
2155     }                                                                                                    
2156                                                                                                          
2157     private void resetAddInfo() {                                                                        
2158         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2159         mPendingAddInfo.screenId = -1;                                                                   
2160         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2161         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2162         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2163         mPendingAddInfo.dropPos = null;                                                                  
2164     }                                                                                                    
2165                                                                                                          
2166     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2167             final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {            
2168         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2169     }                                                                                                    
2170                                                                                                          
2171     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final AppWidgetHostView boundWidget🔵
2172         if (appWidgetInfo.configure != null) {                                                           
2173             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2174             mPendingAddWidgetId = appWidgetId;                                                           
2175             // Launch over to configure widget, if needed                                                
2176             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this, mAppWidgetHost, REQUE🔵
2177         } else {                                                                                         
2178             // Otherwise just add it                                                                     
2179             Runnable onComplete = new Runnable() {                                                       
2180                 @Override                                                                                
2181                 public void run() {                                                                      
2182                     // Exit spring loaded mode if necessary after adding the widget                      
2183                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);   
2184                 }                                                                                        
2185             };                                                                                           
2186             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget, appWidgetInfo);
2187             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2188         }                                                                                                
2189     }                                                                                                    
2190                                                                                                          
2191     protected void moveToCustomContentScreen(boolean animate) {                                          
2192         // Close any folders that may be open.                                                           
2193         closeFolder();                                                                                   
2194         mWorkspace.moveToCustomContentScreen(animate);                                                   
2195     }                                                                                                    
2196                                                                                                          
2197     /**                                                                                                  
2198      * Process a shortcut drop.                                                                          
2199      *                                                                                                   
2200      * @param componentName The name of the component                                                    
2201      * @param screenId The ID of the screen where it should be added                                     
2202      * @param cell The cell it should be added to, optional                                              
2203      * @param position The location on the screen where it was dropped, optional                         
2204      */                                                                                                  
2205     void processShortcutFromDrop(ComponentName componentName, long container, long screenId,             
2206             int[] cell, int[] loc) {                                                                     
2207         resetAddInfo();                                                                                  
2208         mPendingAddInfo.container = container;                                                           
2209         mPendingAddInfo.screenId = screenId;                                                             
2210         mPendingAddInfo.dropPos = loc;                                                                   
2211                                                                                                          
2212         if (cell != null) {                                                                              
2213             mPendingAddInfo.cellX = cell[0];                                                             
2214             mPendingAddInfo.cellY = cell[1];                                                             
2215         }                                                                                                
2216                                                                                                          
2217         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2218         createShortcutIntent.setComponent(componentName);                                                
2219         processShortcut(createShortcutIntent);                                                           
2220     }                                                                                                    
2221                                                                                                          
2222     /**                                                                                                  
2223      * Process a widget drop.                                                                            
2224      *                                                                                                   
2225      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2226      * @param screenId The ID of the screen where it should be added                                     
2227      * @param cell The cell it should be added to, optional                                              
2228      * @param position The location on the screen where it was dropped, optional                         
2229      */                                                                                                  
2230     void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId, int[] cell, int[]🔵
2231         resetAddInfo();                                                                                  
2232         mPendingAddInfo.container = info.container = container;                                          
2233         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2234         mPendingAddInfo.dropPos = loc;                                                                   
2235         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2236         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2237         if (cell != null) {                                                                              
2238             mPendingAddInfo.cellX = cell[0];                                                             
2239             mPendingAddInfo.cellY = cell[1];                                                             
2240         }                                                                                                
2241         if (span != null) {                                                                              
2242             mPendingAddInfo.spanX = span[0];                                                             
2243             mPendingAddInfo.spanY = span[1];                                                             
2244         }                                                                                                
2245         AppWidgetHostView hostView = info.boundWidget;                                                   
2246         int appWidgetId;                                                                                 
2247         if (hostView != null) {                                                                          
2248             appWidgetId = hostView.getAppWidgetId();                                                     
2249             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2250         } else {                                                                                         
2251             // In this case, we either need to start an activity to get permission to bind               
2252             // the widget, or we need to start an activity to configure the widget, or both.             
2253             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2254             Bundle options = info.bindOptions;                                                           
2255             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.info, options)🔵
2256             if (success) {                                                                               
2257                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2258             } else {                                                                                     
2259                 mPendingAddWidgetInfo = info.info;                                                       
2260                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2261                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2262                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2263                 mAppWidgetManager.getUser(mPendingAddWidgetInfo).addToIntent(intent, AppWidgetManager.EXT🔵
2264                 // TODO: we need to make sure that this accounts for the options bundle.                 
2265                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2266                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2267             }                                                                                            
2268         }                                                                                                
2269     }                                                                                                    
2270                                                                                                          
2271     void processShortcut(Intent intent) {                                                                
2272         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2273     }                                                                                                    
2274                                                                                                          
2275     void processWallpaper(Intent intent) {                                                               
2276         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2277     }                                                                                                    
2278                                                                                                          
2279     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2280             int cellY) {                                                                                 
2281         final FolderInfo folderInfo = new FolderInfo();                                                  
2282         folderInfo.title = getText(R.string.folder_name);                                                
2283                                                                                                          
2284         // Update the model                                                                              
2285         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,    
2286                 false);                                                                                  
2287         sFolders.put(folderInfo.id, folderInfo);                                                         
2288                                                                                                          
2289         // Create the view                                                                               
2290         FolderIcon newFolder =                                                                           
2291             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2292         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2293                 isWorkspaceLocked());                                                                    
2294         // Force measure the new folder icon                                                             
2295         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2296         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2297         return newFolder;                                                                                
2298     }                                                                                                    
2299                                                                                                          
2300     void removeFolder(FolderInfo folder) {                                                               
2301         sFolders.remove(folder.id);                                                                      
2302     }                                                                                                    
2303                                                                                                          
2304     protected ComponentName getWallpaperPickerComponent() {                                              
2305         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());     
2306     }                                                                                                    
2307                                                                                                          
2308     /**                                                                                                  
2309      * Registers various content observers. The current implementation registers                         
2310      * only a favorites observer to keep track of the favorites applications.                            
2311      */                                                                                                  
2312     private void registerContentObservers() {                                                            
2313         ContentResolver resolver = getContentResolver();                                                 
2314         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2315                 true, mWidgetObserver);                                                                  
2316     }                                                                                                    
2317                                                                                                          
2318     @Override                                                                                            
2319     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2320         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2321             switch (event.getKeyCode()) {                                                                
2322                 case KeyEvent.KEYCODE_HOME:                                                              
2323                     return true;                                                                         
2324                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2325                     if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                        
2326                         dumpState();                                                                     
2327                         return true;                                                                     
2328                     }                                                                                    
2329                     break;                                                                               
2330             }                                                                                            
2331         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2332             switch (event.getKeyCode()) {                                                                
2333                 case KeyEvent.KEYCODE_HOME:                                                              
2334                     return true;                                                                         
2335             }                                                                                            
2336         }                                                                                                
2337                                                                                                          
2338         return super.dispatchKeyEvent(event);                                                            
2339     }                                                                                                    
2340                                                                                                          
2341     @Override                                                                                            
2342     public void onBackPressed() {                                                                        
2343         if (isAllAppsVisible()) {                                                                        
2344             if (mAppsCustomizeContent.getContentType() ==                                                
2345                     AppsCustomizePagedView.ContentType.Applications) {                                   
2346                 showWorkspace(true);                                                                     
2347             } else {                                                                                     
2348                 showOverviewMode(true);                                                                  
2349             }                                                                                            
2350         } else if (mWorkspace.isInOverviewMode()) {                                                      
2351             mWorkspace.exitOverviewMode(true);                                                           
2352         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2353             Folder openFolder = mWorkspace.getOpenFolder();                                              
2354             if (openFolder.isEditingName()) {                                                            
2355                 openFolder.dismissEditingName();                                                         
2356             } else {                                                                                     
2357                 closeFolder();                                                                           
2358             }                                                                                            
2359         } else {                                                                                         
2360             mWorkspace.exitWidgetResizeMode();                                                           
2361                                                                                                          
2362             // Back button is a no-op here, but give at least some feedback for the button press         
2363             mWorkspace.showOutlinesTemporarily();                                                        
2364         }                                                                                                
2365     }                                                                                                    
2366                                                                                                          
2367     /**                                                                                                  
2368      * Re-listen when widgets are reset.                                                                 
2369      */                                                                                                  
2370     private void onAppWidgetReset() {                                                                    
2371         if (mAppWidgetHost != null) {                                                                    
2372             mAppWidgetHost.startListening();                                                             
2373         }                                                                                                
2374     }                                                                                                    
2375                                                                                                          
2376     /**                                                                                                  
2377      * Launches the intent referred by the clicked shortcut.                                             
2378      *                                                                                                   
2379      * @param v The view representing the clicked shortcut.                                              
2380      */                                                                                                  
2381     public void onClick(View v) {                                                                        
2382         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2383         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2384         if (v.getWindowToken() == null) {                                                                
2385             return;                                                                                      
2386         }                                                                                                
2387         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2388             return;                                                                                      
2389         }                                                                                                
2390         if (v instanceof Workspace) {                                                                    
2391             if (mWorkspace.isInOverviewMode()) {                                                         
2392                 mWorkspace.exitOverviewMode(true);                                                       
2393             }                                                                                            
2394             return;                                                                                      
2395         }                                                                                                
2396         if (v instanceof CellLayout) {                                                                   
2397             if (mWorkspace.isInOverviewMode()) {                                                         
2398                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2399             }                                                                                            
2400         }                                                                                                
2401         Object tag = v.getTag();                                                                         
2402         if (tag instanceof ShortcutInfo) {                                                               
2403             onClickAppShortcut(v);                                                                       
2404         } else if (tag instanceof FolderInfo) {                                                          
2405             if (v instanceof FolderIcon) {                                                               
2406                 onClickFolderIcon(v);                                                                    
2407             }                                                                                            
2408         } else if (v == mAllAppsButton) {                                                                
2409             onClickAllAppsButton(v);                                                                     
2410         } else if (tag instanceof AppInfo) {                                                             
2411             startAppShortcutOrInfoActivity(v);                                                           
2412         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2413             if (v instanceof PendingAppWidgetHostView) {                                                 
2414                 onClickPendingWidget(((PendingAppWidgetHostView) (v)));                                  
2415             }                                                                                            
2416         }                                                                                                
2417     }                                                                                                    
2418                                                                                                          
2419     public void onClickPagedViewIcon(View v) {                                                           
2420         startAppShortcutOrInfoActivity(v);                                                               
2421     }                                                                                                    
2422                                                                                                          
2423     public boolean onTouch(View v, MotionEvent event) {                                                  
2424         return false;                                                                                    
2425     }                                                                                                    
2426                                                                                                          
2427     /**                                                                                                  
2428      * Event handler for the app widget view which has not fully restored.                               
2429      */                                                                                                  
2430     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2431         final LauncherAppWidgetInfo info = ((LauncherAppWidgetInfo) (v.getTag()));                       
2432         if (v.isReadyForClickSetup()) {                                                                  
2433             int widgetId = info.appWidgetId;                                                             
2434             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2435             if (appWidgetInfo != null) {                                                                 
2436                 mPendingAddWidgetInfo = appWidgetInfo;                                                   
2437                 mPendingAddInfo.copyFrom(info);                                                          
2438                 mPendingAddWidgetId = widgetId;                                                          
2439                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo, info.appWidge🔵
2440             }                                                                                            
2441         } else if (info.installProgress < 0) {                                                           
2442             // The install has not been queued                                                           
2443             final String packageName = info.providerName.getPackageName();                               
2444             showBrokenAppInstallDialog(packageName, new DialogInterface.OnClickListener() {              
2445                 public void onClick(DialogInterface dialog, int id) {                                    
2446                     startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);            
2447                 }                                                                                        
2448             });                                                                                          
2449         } else {                                                                                         
2450             // Download has started.                                                                     
2451             final String packageName = info.providerName.getPackageName();                               
2452             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2453         }                                                                                                
2454     }                                                                                                    
2455                                                                                                          
2456     /**                                                                                                  
2457      * Event handler for the search button                                                               
2458      *                                                                                                   
2459      * @param v The view that was clicked.                                                               
2460      */                                                                                                  
2461     public void onClickSearchButton(View v) {                                                            
2462         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2463                                                                                                          
2464         onSearchRequested();                                                                             
2465     }                                                                                                    
2466                                                                                                          
2467     /**                                                                                                  
2468      * Event handler for the voice button                                                                
2469      *                                                                                                   
2470      * @param v The view that was clicked.                                                               
2471      */                                                                                                  
2472     public void onClickVoiceButton(View v) {                                                             
2473         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2474                                                                                                          
2475         startVoice();                                                                                    
2476     }                                                                                                    
2477                                                                                                          
2478     public void startVoice() {                                                                           
2479         try {                                                                                            
2480             final SearchManager searchManager =                                                          
2481                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);                            
2482             ComponentName activityName = searchManager.getGlobalSearchActivity();                        
2483             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2484             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2485             if (activityName != null) {                                                                  
2486                 intent.setPackage(activityName.getPackageName());                                        
2487             }                                                                                            
2488             startActivity(null, intent, "onClickVoiceButton");                                           
2489         } catch (ActivityNotFoundException e) {                                                          
2490             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
2491             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                              
2492             startActivitySafely(null, intent, "onClickVoiceButton");                                     
2493         }                                                                                                
2494     }                                                                                                    
2495                                                                                                          
2496     /**                                                                                                  
2497      * Event handler for the "grid" button that appears on the home screen, which                        
2498      * enters all apps mode.                                                                             
2499      *                                                                                                   
2500      * @param v The view that was clicked.                                                               
2501      */                                                                                                  
2502     protected void onClickAllAppsButton(View v) {                                                        
2503         if (LOGD) {                                                                                      
2504             Log.d(TAG, "onClickAllAppsButton");                                                          
2505         }                                                                                                
2506         if (isAllAppsVisible()) {                                                                        
2507             showWorkspace(true);                                                                         
2508         } else {                                                                                         
2509             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                   
2510         }                                                                                                
2511     }                                                                                                    
2512                                                                                                          
2513     private void showBrokenAppInstallDialog(final String packageName, DialogInterface.OnClickListener onS🔵
2514         new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault)).setTi🔵
2515             public void onClick(DialogInterface dialog, int id) {                                        
2516                 final UserHandleCompat user = UserHandleCompat.myUserHandle();                           
2517                 mWorkspace.removeAbandonedPromise(packageName, user);                                    
2518             }                                                                                            
2519         }).create().show();                                                                              
2520         return;                                                                                          
2521     }                                                                                                    
2522                                                                                                          
2523     /**                                                                                                  
2524      * Event handler for an app shortcut click.                                                          
2525      *                                                                                                   
2526      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2527      */                                                                                                  
2528     protected void onClickAppShortcut(final View v) {                                                    
2529         if (LOGD) {                                                                                      
2530             Log.d(TAG, "onClickAppShortcut");                                                            
2531         }                                                                                                
2532         Object tag = v.getTag();                                                                         
2533         if (!(tag instanceof ShortcutInfo)) {                                                            
2534             throw new IllegalArgumentException("Input must be a Shortcut");                              
2535         }                                                                                                
2536         // Open shortcut                                                                                 
2537         final ShortcutInfo shortcut = ((ShortcutInfo) (tag));                                            
2538         final Intent intent = shortcut.intent;                                                           
2539         // Check for special shortcuts                                                                   
2540         if (intent.getComponent() != null) {                                                             
2541             final String shortcutClass = intent.getComponent().getClassName();                           
2542             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2543                 MemoryDumpActivity.startDump(this);                                                      
2544                 return;                                                                                  
2545             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2546                 toggleShowWeightWatcher();                                                               
2547                 return;                                                                                  
2548             }                                                                                            
2549         }                                                                                                
2550         // Check for abandoned promise                                                                   
2551         if (((v instanceof BubbleTextView) && shortcut.isPromise()) && (!shortcut.hasStatusFlag(ShortcutI🔵
2552             showBrokenAppInstallDialog(shortcut.getTargetComponent().getPackageName(), new DialogInterfac🔵
2553                         public void onClick(DialogInterface dialog, int id) {                            
2554                             startAppShortcutOrInfoActivity(v);                                           
2555                         }                                                                                
2556             });                                                                                          
2557             return;                                                                                      
2558         }                                                                                                
2559         // Start activities                                                                              
2560         startAppShortcutOrInfoActivity(v);                                                               
2561     }                                                                                                    
2562                                                                                                          
2563     private void startAppShortcutOrInfoActivity(View v) {                                                
2564         Object tag = v.getTag();                                                                         
2565         final ShortcutInfo shortcut;                                                                     
2566         final Intent intent;                                                                             
2567         if (tag instanceof ShortcutInfo) {                                                               
2568             shortcut = ((ShortcutInfo) (tag));                                                           
2569             intent = shortcut.intent;                                                                    
2570             int[] pos = new int[2];                                                                      
2571             v.getLocationOnScreen(pos);                                                                  
2572             intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight()🔵
2573         } else if (tag instanceof AppInfo) {                                                             
2574             shortcut = null;                                                                             
2575             intent = ((AppInfo) (tag)).intent;                                                           
2576         } else {                                                                                         
2577             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2578         }                                                                                                
2579         boolean success = startActivitySafely(v, intent, tag);                                           
2580         mStats.recordLaunch(intent, shortcut);                                                           
2581         if (success && (v instanceof BubbleTextView)) {                                                  
2582             mWaitingForResume = ((BubbleTextView) (v));                                                  
2583             mWaitingForResume.setStayPressed(true);                                                      
2584         }                                                                                                
2585     }                                                                                                    
2586                                                                                                          
2587     /**                                                                                                  
2588      * Event handler for a folder icon click.                                                            
2589      *                                                                                                   
2590      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2591      */                                                                                                  
2592     protected void onClickFolderIcon(View v) {                                                           
2593         if (LOGD) {                                                                                      
2594             Log.d(TAG, "onClickFolder");                                                                 
2595         }                                                                                                
2596         if (!(v instanceof FolderIcon)) {                                                                
2597             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2598         }                                                                                                
2599         FolderIcon folderIcon = ((FolderIcon) (v));                                                      
2600         final FolderInfo info = folderIcon.getFolderInfo();                                              
2601         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2602         // If the folder info reports that the associated folder is open, then verify that               
2603         // it is actually opened. There have been a few instances where this gets out of sync.           
2604         if (info.opened && (openFolder == null)) {                                                       
2605             Log.d(TAG, ((((("Folder info marked as open, but associated folder is not open. Screen: " + i🔵
2606             info.opened = false;                                                                         
2607         }                                                                                                
2608         if ((!info.opened) && (!folderIcon.getFolder().isDestroyed())) {                                 
2609             // Close any open folder                                                                     
2610             closeFolder();                                                                               
2611             // Open the requested folder                                                                 
2612             openFolder(folderIcon);                                                                      
2613         } else {                                                                                         
2614             // Find the open folder...                                                                   
2615             int folderScreen;                                                                            
2616             if (openFolder != null) {                                                                    
2617                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2618                 // .. and close it                                                                       
2619                 closeFolder(openFolder);                                                                 
2620                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2621                     // Close any folder open on the current screen                                       
2622                     closeFolder();                                                                       
2623                     // Pull the folder onto this screen                                                  
2624                     openFolder(folderIcon);                                                              
2625                 }                                                                                        
2626             }                                                                                            
2627         }                                                                                                
2628     }                                                                                                    
2629                                                                                                          
2630     /**                                                                                                  
2631      * Event handler for the (Add) Widgets button that appears after a long press                        
2632      * on the home screen.                                                                               
2633      */                                                                                                  
2634     protected void onClickAddWidgetButton(View view) {                                                   
2635         if (LOGD) {                                                                                      
2636             Log.d(TAG, "onClickAddWidgetButton");                                                        
2637         }                                                                                                
2638         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                             
2639     }                                                                                                    
2640                                                                                                          
2641     /**                                                                                                  
2642      * Event handler for the wallpaper picker button that appears after a long press                     
2643      * on the home screen.                                                                               
2644      */                                                                                                  
2645     protected void onClickWallpaperPicker(View v) {                                                      
2646         if (LOGD) {                                                                                      
2647             Log.d(TAG, "onClickWallpaperPicker");                                                        
2648         }                                                                                                
2649         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                            
2650         pickWallpaper.setComponent(getWallpaperPickerComponent());                                       
2651         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                   
2652     }                                                                                                    
2653                                                                                                          
2654     /**                                                                                                  
2655      * Event handler for a click on the settings button that appears after a long press                  
2656      * on the home screen.                                                                               
2657      */                                                                                                  
2658     protected void onClickSettingsButton(View v) {                                                       
2659         if (LOGD) {                                                                                      
2660             Log.d(TAG, "onClickSettingsButton");                                                         
2661         }                                                                                                
2662     }                                                                                                    
2663                                                                                                          
2664     public void onTouchDownAllAppsButton(View v) {                                                       
2665         // Provide the same haptic feedback that the system offers for virtual keys.                     
2666         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2667     }                                                                                                    
2668                                                                                                          
2669     public void performHapticFeedbackOnTouchDown(View v) {                                               
2670         // Provide the same haptic feedback that the system offers for virtual keys.                     
2671         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2672     }                                                                                                    
2673                                                                                                          
2674     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2675         if (mHapticFeedbackTouchListener == null) {                                                      
2676             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2677                 @Override                                                                                
2678                 public boolean onTouch(View v, MotionEvent event) {                                      
2679                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2680                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2681                     }                                                                                    
2682                     return false;                                                                        
2683                 }                                                                                        
2684             };                                                                                           
2685         }                                                                                                
2686         return mHapticFeedbackTouchListener;                                                             
2687     }                                                                                                    
2688                                                                                                          
2689     public void onDragStarted(View view) {                                                               
2690     }                                                                                                    
2691                                                                                                          
2692     /**                                                                                                  
2693      * Called when the user stops interacting with the launcher.                                         
2694      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2695      */                                                                                                  
2696     protected void onInteractionEnd() {}                                                                 
2697                                                                                                          
2698     /**                                                                                                  
2699      * Called when the user starts interacting with the launcher.                                        
2700      * The possible interactions are:                                                                    
2701      *  - open all apps                                                                                  
2702      *  - reorder an app shortcut, or a widget                                                           
2703      *  - open the overview mode.                                                                        
2704      * This is a good time to stop doing things that only make sense                                     
2705      * when the user is on the homescreen and not doing housekeeping.                                    
2706      */                                                                                                  
2707     protected void onInteractionBegin() {}                                                               
2708                                                                                                          
2709     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2710         String packageName = componentName.getPackageName();                                             
2711         try {                                                                                            
2712             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2713             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2714             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2715         } catch (java.lang.SecurityException e) {                                                        
2716             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2717             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2718         } catch (ActivityNotFoundException e) {                                                          
2719             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2720             Log.e(TAG, "Unable to launch settings");                                                     
2721         }                                                                                                
2722     }                                                                                                    
2723                                                                                                          
2724     // returns true if the activity was started                                                          
2725     boolean startApplicationUninstallActivity(ComponentName componentName, int flags, UserHandleCompat us🔵
2726         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2727             // System applications cannot be installed. For now, show a toast explaining that.           
2728             // We may give them the option of disabling apps this way.                                   
2729             int messageId = R.string.uninstall_system_app_text;                                          
2730             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2731             return false;                                                                                
2732         } else {                                                                                         
2733             String packageName = componentName.getPackageName();                                         
2734             String className = componentName.getClassName();                                             
2735             Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package", packageName, classN🔵
2736             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);  
2737             if (user != null) {                                                                          
2738                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2739             }                                                                                            
2740             startActivity(intent);                                                                       
2741             return true;                                                                                 
2742         }                                                                                                
2743     }                                                                                                    
2744                                                                                                          
2745     boolean startActivity(View v, Intent intent, Object tag) {                                           
2746         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2747         try {                                                                                            
2748             // Only launch using the new animation if the shortcut has not opted out (this is a          
2749             // private contract between launcher and may be ignored in the future).                      
2750             boolean useLaunchAnimation = (v != null) && (!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIM🔵
2751             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2752             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2753             UserHandleCompat user = null;                                                                
2754             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2755                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2756                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2757             }                                                                                            
2758             Bundle optsBundle = null;                                                                    
2759             if (useLaunchAnimation) {                                                                    
2760                 ActivityOptions opts = (Utilities.isLmpOrAbove()) ? ActivityOptions.makeCustomAnimation(t🔵
2761                 optsBundle = opts.toBundle();                                                            
2762             }                                                                                            
2763             if ((user == null) || user.equals(UserHandleCompat.myUserHandle())) {                        
2764                 // Could be launching some bookkeeping activity                                          
2765                 startActivity(intent, optsBundle);                                                       
2766             } else {                                                                                     
2767                 // TODO Component can be null when shortcuts are supported for secondary user            
2768                 launcherApps.startActivityForProfile(intent.getComponent(), user, intent.getSourceBounds(🔵
2769             }                                                                                            
2770             return true;                                                                                 
2771         } catch (java.lang.SecurityException e) {                                                        
2772             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2773             Log.e(TAG, (((((("Launcher does not have the permission to launch " + intent) + ". Make sure 🔵
2774         }                                                                                                
2775         return false;                                                                                    
2776     }                                                                                                    
2777                                                                                                          
2778     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2779         boolean success = false;                                                                         
2780         if (mIsSafeModeEnabled && (!Utilities.isSystemApp(this, intent))) {                              
2781             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2782             return false;                                                                                
2783         }                                                                                                
2784         try {                                                                                            
2785             success = startActivity(v, intent, tag);                                                     
2786         } catch (ActivityNotFoundException e) {                                                          
2787             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2788             Log.e(TAG, (("Unable to launch. tag=" + tag) + " intent=") + intent, e);                     
2789         }                                                                                                
2790         return success;                                                                                  
2791     }                                                                                                    
2792                                                                                                          
2793     /**                                                                                                  
2794      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2795      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2796      */                                                                                                  
2797     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2798         final int width = fi.getMeasuredWidth();                                                         
2799         final int height = fi.getMeasuredHeight();                                                       
2800                                                                                                          
2801         // Lazy load ImageView, Bitmap and Canvas                                                        
2802         if (mFolderIconImageView == null) {                                                              
2803             mFolderIconImageView = new ImageView(this);                                                  
2804         }                                                                                                
2805         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2806                 mFolderIconBitmap.getHeight() != height) {                                               
2807             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2808             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2809         }                                                                                                
2810                                                                                                          
2811         DragLayer.LayoutParams lp;                                                                       
2812         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2813             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2814         } else {                                                                                         
2815             lp = new DragLayer.LayoutParams(width, height);                                              
2816         }                                                                                                
2817                                                                                                          
2818         // The layout from which the folder is being opened may be scaled, adjust the starting           
2819         // view size by this scale factor.                                                               
2820         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2821         lp.customPosition = true;                                                                        
2822         lp.x = mRectForFolderAnimation.left;                                                             
2823         lp.y = mRectForFolderAnimation.top;                                                              
2824         lp.width = (int) (scale * width);                                                                
2825         lp.height = (int) (scale * height);                                                              
2826                                                                                                          
2827         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
2828         fi.draw(mFolderIconCanvas);                                                                      
2829         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
2830         if (fi.getFolder() != null) {                                                                    
2831             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
2832             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
2833         }                                                                                                
2834         // Just in case this image view is still in the drag layer from a previous animation,            
2835         // we remove it and re-add it.                                                                   
2836         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
2837             mDragLayer.removeView(mFolderIconImageView);                                                 
2838         }                                                                                                
2839         mDragLayer.addView(mFolderIconImageView, lp);                                                    
2840         if (fi.getFolder() != null) {                                                                    
2841             fi.getFolder().bringToFront();                                                               
2842         }                                                                                                
2843     }                                                                                                    
2844                                                                                                          
2845     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
2846         if (fi == null) {                                                                                
2847             return;                                                                                      
2848         }                                                                                                
2849         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
2850         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5F);                      
2851         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5F);                      
2852         FolderInfo info = ((FolderInfo) (fi.getTag()));                                                  
2853         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
2854             CellLayout cl = ((CellLayout) (fi.getParent().getParent()));                                 
2855             CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) (fi.getLayoutParams()));             
2856             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
2857         }                                                                                                
2858         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
2859         copyFolderIconToImage(fi);                                                                       
2860         fi.setVisibility(View.INVISIBLE);                                                                
2861         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha, scaleX,🔵
2862         if (Utilities.isLmpOrAbove()) {                                                                  
2863             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
2864         }                                                                                                
2865         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2866         oa.start();                                                                                      
2867     }                                                                                                    
2868                                                                                                          
2869     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
2870         if (fi == null) {                                                                                
2871             return;                                                                                      
2872         }                                                                                                
2873         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0F);                        
2874         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0F);                      
2875         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0F);                      
2876         final CellLayout cl = ((CellLayout) (fi.getParent().getParent()));                               
2877         // We remove and re-draw the FolderIcon in-case it has changed                                   
2878         mDragLayer.removeView(mFolderIconImageView);                                                     
2879         copyFolderIconToImage(fi);                                                                       
2880         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha, scaleX,🔵
2881         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
2882         oa.addListener(new AnimatorListenerAdapter() {                                                   
2883             @Override                                                                                    
2884             public void onAnimationEnd(Animator animation) {                                             
2885                 if (cl != null) {                                                                        
2886                     cl.clearFolderLeaveBehind();                                                         
2887                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
2888                     mDragLayer.removeView(mFolderIconImageView);                                         
2889                     fi.setVisibility(View.VISIBLE);                                                      
2890                 }                                                                                        
2891             }                                                                                            
2892         });                                                                                              
2893         oa.start();                                                                                      
2894     }                                                                                                    
2895                                                                                                          
2896     /**                                                                                                  
2897      * Opens the user folder described by the specified tag. The opening of the folder                   
2898      * is animated relative to the specified View. If the View is null, no animation                     
2899      * is played.                                                                                        
2900      *                                                                                                   
2901      * @param folderInfo The FolderInfo describing the folder to open.                                   
2902      */                                                                                                  
2903     public void openFolder(FolderIcon folderIcon) {                                                      
2904         Folder folder = folderIcon.getFolder();                                                          
2905         FolderInfo info = folder.mInfo;                                                                  
2906                                                                                                          
2907         info.opened = true;                                                                              
2908                                                                                                          
2909         // Just verify that the folder hasn't already been added to the DragLayer.                       
2910         // There was a one-off crash where the folder had a parent already.                              
2911         if (folder.getParent() == null) {                                                                
2912             mDragLayer.addView(folder);                                                                  
2913             mDragController.addDropTarget((DropTarget) folder);                                          
2914         } else {                                                                                         
2915             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
2916                     folder.getParent() + ").");                                                          
2917         }                                                                                                
2918         folder.animateOpen();                                                                            
2919         growAndFadeOutFolderIcon(folderIcon);                                                            
2920                                                                                                          
2921         // Notify the accessibility manager that this folder "window" has appeared and occluded          
2922         // the workspace items                                                                           
2923         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
2924         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
2925     }                                                                                                    
2926                                                                                                          
2927     public void closeFolder() {                                                                          
2928         Folder folder = (mWorkspace != null) ? mWorkspace.getOpenFolder() : null;                        
2929         if (folder != null) {                                                                            
2930             if (folder.isEditingName()) {                                                                
2931                 folder.dismissEditingName();                                                             
2932             }                                                                                            
2933             closeFolder(folder);                                                                         
2934         }                                                                                                
2935     }                                                                                                    
2936                                                                                                          
2937     void closeFolder(Folder folder) {                                                                    
2938         folder.getInfo().opened = false;                                                                 
2939                                                                                                          
2940         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
2941         if (parent != null) {                                                                            
2942             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
2943             shrinkAndFadeInFolderIcon(fi);                                                               
2944         }                                                                                                
2945         folder.animateClosed();                                                                          
2946                                                                                                          
2947         // Notify the accessibility manager that this folder "window" has disappeard and no              
2948         // longer occludeds the workspace items                                                          
2949         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
2950     }                                                                                                    
2951                                                                                                          
2952     public boolean onLongClick(View v) {                                                                 
2953         if (!isDraggingEnabled()) {                                                                      
2954             return false;                                                                                
2955         }                                                                                                
2956         if (isWorkspaceLocked()) {                                                                       
2957             return false;                                                                                
2958         }                                                                                                
2959         if (mState != State.WORKSPACE) {                                                                 
2960             return false;                                                                                
2961         }                                                                                                
2962         if (v instanceof Workspace) {                                                                    
2963             if (!mWorkspace.isInOverviewMode()) {                                                        
2964                 if (mWorkspace.enterOverviewMode()) {                                                    
2965                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackCo🔵
2966                     return true;                                                                         
2967                 } else {                                                                                 
2968                     return false;                                                                        
2969                 }                                                                                        
2970             } else {                                                                                     
2971                 return false;                                                                            
2972             }                                                                                            
2973         }                                                                                                
2974         CellLayout.CellInfo longClickCellInfo = null;                                                    
2975         View itemUnderLongClick = null;                                                                  
2976         if (v.getTag() instanceof ItemInfo) {                                                            
2977             ItemInfo info = ((ItemInfo) (v.getTag()));                                                   
2978             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
2979             itemUnderLongClick = longClickCellInfo.cell;                                                 
2980             resetAddInfo();                                                                              
2981         }                                                                                                
2982         // The hotseat touch handling does not go through Workspace, and we always allow long press      
2983         // on hotseat items.                                                                             
2984         final boolean inHotseat = isHotseatLayout(v);                                                    
2985         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
2986         if (allowLongPress && (!mDragController.isDragging())) {                                         
2987             if (itemUnderLongClick == null) {                                                            
2988                 // User long pressed on empty space                                                      
2989                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConsta🔵
2990                 if (mWorkspace.isInOverviewMode()) {                                                     
2991                     mWorkspace.startReordering(v);                                                       
2992                 } else {                                                                                 
2993                     mWorkspace.enterOverviewMode();                                                      
2994                 }                                                                                        
2995             } else {                                                                                     
2996                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(mHotseat.getOrderInHotse🔵
2997                 if (!((itemUnderLongClick instanceof Folder) || isAllAppsButton)) {                      
2998                     // User long pressed on an item                                                      
2999                     mWorkspace.startDrag(longClickCellInfo);                                             
3000                 }                                                                                        
3001             }                                                                                            
3002         }                                                                                                
3003         return true;                                                                                     
3004     }                                                                                                    
3005                                                                                                          
3006     boolean isHotseatLayout(View layout) {                                                               
3007         return mHotseat != null && layout != null &&                                                     
3008                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3009     }                                                                                                    
3010                                                                                                          
3011     /**                                                                                                  
3012      * Returns the CellLayout of the specified container at the specified screen.                        
3013      */                                                                                                  
3014     CellLayout getCellLayout(long container, long screenId) {                                            
3015         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3016             if (mHotseat != null) {                                                                      
3017                 return mHotseat.getLayout();                                                             
3018             } else {                                                                                     
3019                 return null;                                                                             
3020             }                                                                                            
3021         } else {                                                                                         
3022             return (CellLayout) mWorkspace.getScreenWithId(screenId);                                    
3023         }                                                                                                
3024     }                                                                                                    
3025                                                                                                          
3026     public boolean isAllAppsVisible() {                                                                  
3027         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);             
3028     }                                                                                                    
3029                                                                                                          
3030     private void setWorkspaceBackground(boolean workspace) {                                             
3031         mLauncherView.setBackground(workspace ?                                                          
3032                 mWorkspaceBackgroundDrawable : null);                                                    
3033     }                                                                                                    
3034                                                                                                          
3035     protected void changeWallpaperVisiblity(boolean visible) {                                           
3036         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3037         int curflags = getWindow().getAttributes().flags                                                 
3038                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3039         if (wpflags != curflags) {                                                                       
3040             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3041         }                                                                                                
3042         setWorkspaceBackground(visible);                                                                 
3043     }                                                                                                    
3044                                                                                                          
3045     private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {    
3046         if (v instanceof LauncherTransitionable) {                                                       
3047             ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);       
3048         }                                                                                                
3049     }                                                                                                    
3050                                                                                                          
3051     private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {      
3052         if (v instanceof LauncherTransitionable) {                                                       
3053             ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);         
3054         }                                                                                                
3055                                                                                                          
3056         // Update the workspace transition step as well                                                  
3057         dispatchOnLauncherTransitionStep(v, 0f);                                                         
3058     }                                                                                                    
3059                                                                                                          
3060     private void dispatchOnLauncherTransitionStep(View v, float t) {                                     
3061         if (v instanceof LauncherTransitionable) {                                                       
3062             ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                              
3063         }                                                                                                
3064     }                                                                                                    
3065                                                                                                          
3066     private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {        
3067         if (v instanceof LauncherTransitionable) {                                                       
3068             ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);           
3069         }                                                                                                
3070                                                                                                          
3071         // Update the workspace transition step as well                                                  
3072         dispatchOnLauncherTransitionStep(v, 1f);                                                         
3073     }                                                                                                    
3074                                                                                                          
3075     /**                                                                                                  
3076      * Things to test when changing the following seven functions.                                       
3077      *   - Home from workspace                                                                           
3078      *          - from center screen                                                                     
3079      *          - from other screens                                                                     
3080      *   - Home from all apps                                                                            
3081      *          - from center screen                                                                     
3082      *          - from other screens                                                                     
3083      *   - Back from all apps                                                                            
3084      *          - from center screen                                                                     
3085      *          - from other screens                                                                     
3086      *   - Launch app from workspace and quit                                                            
3087      *          - with back                                                                              
3088      *          - with home                                                                              
3089      *   - Launch app from all apps and quit                                                             
3090      *          - with back                                                                              
3091      *          - with home                                                                              
3092      *   - Go to a screen that's not the default, then all                                               
3093      *     apps, and launch and app, and go back                                                         
3094      *          - with back                                                                              
3095      *          -with home                                                                               
3096      *   - On workspace, long press power and go back                                                    
3097      *          - with back                                                                              
3098      *          - with home                                                                              
3099      *   - On all apps, long press power and go back                                                     
3100      *          - with back                                                                              
3101      *          - with home                                                                              
3102      *   - On workspace, power off                                                                       
3103      *   - On all apps, power off                                                                        
3104      *   - Launch an app and turn off the screen while in that app                                       
3105      *          - Go back with home key                                                                  
3106      *          - Go back with back key  TODO: make this not go to workspace                             
3107      *          - From all apps                                                                          
3108      *          - From workspace                                                                         
3109      *   - Enter and exit car mode (becuase it causes an extra configuration changed)                    
3110      *          - From all apps                                                                          
3111      *          - From the center workspace                                                              
3112      *          - From another workspace                                                                 
3113      */                                                                                                  
3114                                                                                                          
3115     /**                                                                                                  
3116      * Zoom the camera out from the workspace to reveal 'toView'.                                        
3117      * Assumes that the view to show is anchored at either the very top or very bottom                   
3118      * of the screen.                                                                                    
3119      */                                                                                                  
3120     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {           
3121         AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();         
3122         showAppsCustomizeHelper(animated, springLoaded, contentType);                                    
3123     }                                                                                                    
3124                                                                                                          
3125     private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded, final AppsCu🔵
3126         if (mStateAnimation != null) {                                                                   
3127             mStateAnimation.setDuration(0);                                                              
3128             mStateAnimation.cancel();                                                                    
3129             mStateAnimation = null;                                                                      
3130         }                                                                                                
3131         boolean material = Utilities.isLmpOrAbove();                                                     
3132         final Resources res = getResources();                                                            
3133         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                   
3134         final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);               
3135         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);             
3136         final int itemsAlphaStagger = res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);   
3137         final float scale = ((float) (res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor)));   
3138         final View fromView = mWorkspace;                                                                
3139         final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                       
3140         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3141         Workspace.State workspaceState = (contentType == AppsCustomizePagedView.ContentType.Widgets) ? Wo🔵
3142         Animator workspaceAnim = mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews)🔵
3143         if ((!LauncherAppState.isDisableAllApps()) || (contentType == AppsCustomizePagedView.ContentType.🔵
3144             // Set the content type for the all apps/widgets space                                       
3145             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                  
3146         }                                                                                                
3147         // If for some reason our views aren't initialized, don't animate                                
3148         boolean initialized = getAllAppsButton() != null;                                                
3149         if (animated && initialized) {                                                                   
3150             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3151             final AppsCustomizePagedView content = ((AppsCustomizePagedView) (toView.findViewById(R.id.ap🔵
3152             final View page = content.getPageAt(content.getCurrentPage());                               
3153             final View revealView = toView.findViewById(R.id.fake_page);                                 
3154             final float initialPanelAlpha = 1.0F;                                                        
3155             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;      
3156             if (isWidgetTray) {                                                                          
3157                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                
3158             } else {                                                                                     
3159                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                     
3160             }                                                                                            
3161             // Hide the real page background, and swap in the fake one                                   
3162             content.setPageBackgroundsVisible(false);                                                    
3163             revealView.setVisibility(View.VISIBLE);                                                      
3164             // We need to hide this view as the animation start will be posted.                          
3165             revealView.setAlpha(0);                                                                      
3166             int width = revealView.getMeasuredWidth();                                                   
3167             int height = revealView.getMeasuredHeight();                                                 
3168             float revealRadius = ((float) (Math.sqrt(((width * width) / 4) + ((height * height) / 4)))); 
3169             revealView.setTranslationY(0);                                                               
3170             revealView.setTranslationX(0);                                                               
3171             // Get the y delta between the center of the page and the center of the all apps button      
3172             int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, getAllAppsButto🔵
3173             float alpha = 0;                                                                             
3174             float xDrift = 0;                                                                            
3175             float yDrift = 0;                                                                            
3176             if (material) {                                                                              
3177                 alpha = (isWidgetTray) ? 0.3F : 1.0F;                                                    
3178                 yDrift = (isWidgetTray) ? height / 2 : allAppsToPanelDelta[1];                           
3179                 xDrift = (isWidgetTray) ? 0 : allAppsToPanelDelta[0];                                    
3180             } else {                                                                                     
3181                 yDrift = (2 * height) / 3;                                                               
3182                 xDrift = 0;                                                                              
3183             }                                                                                            
3184             final float initAlpha = alpha;                                                               
3185             revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                     
3186             layerViews.add(revealView);                                                                  
3187             PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1.0F);    
3188             PropertyValuesHolder panelDriftY = PropertyValuesHolder.ofFloat("translationY", yDrift, 0);  
3189             PropertyValuesHolder panelDriftX = PropertyValuesHolder.ofFloat("translationX", xDrift, 0);  
3190             ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView, panelAl🔵
3191             panelAlphaAndDrift.setDuration(revealDuration);                                              
3192             panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                   
3193             mStateAnimation.play(panelAlphaAndDrift);                                                    
3194             if (page != null) {                                                                          
3195                 page.setVisibility(View.VISIBLE);                                                        
3196                 page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3197                 layerViews.add(page);                                                                    
3198                 ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);      
3199                 page.setTranslationY(yDrift);                                                            
3200                 pageDrift.setDuration(revealDuration);                                                   
3201                 pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                        
3202                 pageDrift.setStartDelay(itemsAlphaStagger);                                              
3203                 mStateAnimation.play(pageDrift);                                                         
3204                 page.setAlpha(0.0F);                                                                     
3205                 ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0.0F, 1.0F);           
3206                 itemsAlpha.setDuration(revealDuration);                                                  
3207                 itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5F));                            
3208                 itemsAlpha.setStartDelay(itemsAlphaStagger);                                             
3209                 mStateAnimation.play(itemsAlpha);                                                        
3210             }                                                                                            
3211             View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);               
3212             pageIndicators.setAlpha(0.01F);                                                              
3213             ObjectAnimator indicatorsAlpha = ObjectAnimator.ofFloat(pageIndicators, "alpha", 1.0F);      
3214             indicatorsAlpha.setDuration(revealDuration);                                                 
3215             mStateAnimation.play(indicatorsAlpha);                                                       
3216             if (material) {                                                                              
3217                 final View allApps = getAllAppsButton();                                                 
3218                 int allAppsButtonSize = LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile(🔵
3219                 float startRadius = (isWidgetTray) ? 0 : allAppsButtonSize / 2;                          
3220                 Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2, height /🔵
3221                 reveal.setDuration(revealDuration);                                                      
3222                 reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                           
3223                 reveal.addListener(new AnimatorListenerAdapter() {                                       
3224                     public void onAnimationStart(Animator animation) {                                   
3225                         if (!isWidgetTray) {                                                             
3226                             allApps.setVisibility(View.INVISIBLE);                                       
3227                         }                                                                                
3228                     }                                                                                    
3229                                                                                                          
3230                     public void onAnimationEnd(Animator animation) {                                     
3231                         if (!isWidgetTray) {                                                             
3232                             allApps.setVisibility(View.VISIBLE);                                         
3233                         }                                                                                
3234                     }                                                                                    
3235                 });                                                                                      
3236                 mStateAnimation.play(reveal);                                                            
3237             }                                                                                            
3238             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3239                 @Override                                                                                
3240                 public void onAnimationEnd(Animator animation) {                                         
3241                     dispatchOnLauncherTransitionEnd(fromView, animated, false);                          
3242                     dispatchOnLauncherTransitionEnd(toView, animated, false);                            
3243                     revealView.setVisibility(View.INVISIBLE);                                            
3244                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3245                     if (page != null) {                                                                  
3246                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3247                     }                                                                                    
3248                     content.setPageBackgroundsVisible(true);                                             
3249                     // Hide the search bar                                                               
3250                     if (mSearchDropTargetBar != null) {                                                  
3251                         mSearchDropTargetBar.hideSearchBar(false);                                       
3252                     }                                                                                    
3253                 }                                                                                        
3254             });                                                                                          
3255             if (workspaceAnim != null) {                                                                 
3256                 mStateAnimation.play(workspaceAnim);                                                     
3257             }                                                                                            
3258             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3259             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3260             final AnimatorSet stateAnimation = mStateAnimation;                                          
3261             final Runnable startAnimRunnable = new Runnable() {                                          
3262                 public void run() {                                                                      
3263                     // Check that mStateAnimation hasn't changed while                                   
3264                     // we waited for a layout/draw pass                                                  
3265                     if (mStateAnimation != stateAnimation) {                                             
3266                         return;                                                                          
3267                     }                                                                                    
3268                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3269                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3270                     revealView.setAlpha(initAlpha);                                                      
3271                     if (Utilities.isLmpOrAbove()) {                                                      
3272                         for (int i = 0; i < layerViews.size(); i++) {                                    
3273                             View v = layerViews.get(i);                                                  
3274                             if (v != null) {                                                             
3275                                 boolean attached = true;                                                 
3276                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3277                                     attached = v.isAttachedToWindow();                                   
3278                                 }                                                                        
3279                                 if (attached) {                                                          
3280                                     v.buildLayer();                                                      
3281                                 }                                                                        
3282                             }                                                                            
3283                         }                                                                                
3284                     }                                                                                    
3285                     mStateAnimation.start();                                                             
3286                 }                                                                                        
3287             };                                                                                           
3288             toView.bringToFront();                                                                       
3289             toView.setVisibility(View.VISIBLE);                                                          
3290             toView.post(startAnimRunnable);                                                              
3291         } else {                                                                                         
3292             toView.setTranslationX(0.0F);                                                                
3293             toView.setTranslationY(0.0F);                                                                
3294             toView.setScaleX(1.0F);                                                                      
3295             toView.setScaleY(1.0F);                                                                      
3296             toView.setVisibility(View.VISIBLE);                                                          
3297             toView.bringToFront();                                                                       
3298             if ((!springLoaded) && (!LauncherAppState.getInstance().isScreenLarge())) {                  
3299                 // Hide the search bar                                                                   
3300                 if (mSearchDropTargetBar != null) {                                                      
3301                     mSearchDropTargetBar.hideSearchBar(false);                                           
3302                 }                                                                                        
3303             }                                                                                            
3304             dispatchOnLauncherTransitionPrepare(fromView, animated, false);                              
3305             dispatchOnLauncherTransitionStart(fromView, animated, false);                                
3306             dispatchOnLauncherTransitionEnd(fromView, animated, false);                                  
3307             dispatchOnLauncherTransitionPrepare(toView, animated, false);                                
3308             dispatchOnLauncherTransitionStart(toView, animated, false);                                  
3309             dispatchOnLauncherTransitionEnd(toView, animated, false);                                    
3310         }                                                                                                
3311     }                                                                                                    
3312                                                                                                          
3313     /**                                                                                                  
3314      * Zoom the camera back into the workspace, hiding 'fromView'.                                       
3315      * This is the opposite of showAppsCustomizeHelper.                                                  
3316      * @param animated If true, the transition will be animated.                                         
3317      */                                                                                                  
3318     private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated, final boolean s🔵
3319         if (mStateAnimation != null) {                                                                   
3320             mStateAnimation.setDuration(0);                                                              
3321             mStateAnimation.cancel();                                                                    
3322             mStateAnimation = null;                                                                      
3323         }                                                                                                
3324         boolean material = Utilities.isLmpOrAbove();                                                     
3325         Resources res = getResources();                                                                  
3326         final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                  
3327         final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);           
3328         final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);            
3329         final int itemsAlphaStagger = res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);   
3330         final float scaleFactor = ((float) (res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor)🔵
3331         final View fromView = mAppsCustomizeTabHost;                                                     
3332         final View toView = mWorkspace;                                                                  
3333         Animator workspaceAnim = null;                                                                   
3334         final ArrayList<View> layerViews = new ArrayList<View>();                                        
3335         if (toState == Workspace.State.NORMAL) {                                                         
3336             workspaceAnim = mWorkspace.getChangeStateAnimation(toState, animated, layerViews);           
3337         } else if ((toState == Workspace.State.SPRING_LOADED) || (toState == Workspace.State.OVERVIEW)) {
3338             workspaceAnim = mWorkspace.getChangeStateAnimation(toState, animated, layerViews);           
3339         }                                                                                                
3340         // If for some reason our views aren't initialized, don't animate                                
3341         boolean initialized = getAllAppsButton() != null;                                                
3342         if (animated && initialized) {                                                                   
3343             mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                     
3344             if (workspaceAnim != null) {                                                                 
3345                 mStateAnimation.play(workspaceAnim);                                                     
3346             }                                                                                            
3347             final AppsCustomizePagedView content = ((AppsCustomizePagedView) (fromView.findViewById(R.id.🔵
3348             final View page = content.getPageAt(content.getNextPage());                                  
3349             // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases        
3350             int count = content.getChildCount();                                                         
3351             for (int i = 0; i < count; i++) {                                                            
3352                 View child = content.getChildAt(i);                                                      
3353                 if (child != page) {                                                                     
3354                     child.setVisibility(View.INVISIBLE);                                                 
3355                 }                                                                                        
3356             }                                                                                            
3357             final View revealView = fromView.findViewById(R.id.fake_page);                               
3358             // hideAppsCustomizeHelper is called in some cases when it is already hidden                 
3359             // don't perform all these no-op animations. In particularly, this was causing               
3360             // the all-apps button to pop in and out.                                                    
3361             if (fromView.getVisibility() == View.VISIBLE) {                                              
3362                 AppsCustomizePagedView.ContentType contentType = content.getContentType();               
3363                 final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;  
3364                 if (isWidgetTray) {                                                                      
3365                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));            
3366                 } else {                                                                                 
3367                     revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                 
3368                 }                                                                                        
3369                 int width = revealView.getMeasuredWidth();                                               
3370                 int height = revealView.getMeasuredHeight();                                             
3371                 float revealRadius = ((float) (Math.sqrt(((width * width) / 4) + ((height * height) / 4))🔵
3372                 // Hide the real page background, and swap in the fake one                               
3373                 revealView.setVisibility(View.VISIBLE);                                                  
3374                 content.setPageBackgroundsVisible(false);                                                
3375                 final View allAppsButton = getAllAppsButton();                                           
3376                 revealView.setTranslationY(0);                                                           
3377                 int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView, allAppsButt🔵
3378                 float xDrift = 0;                                                                        
3379                 float yDrift = 0;                                                                        
3380                 if (material) {                                                                          
3381                     yDrift = (isWidgetTray) ? height / 2 : allAppsToPanelDelta[1];                       
3382                     xDrift = (isWidgetTray) ? 0 : allAppsToPanelDelta[0];                                
3383                 } else {                                                                                 
3384                     yDrift = (5 * height) / 4;                                                           
3385                     xDrift = 0;                                                                          
3386                 }                                                                                        
3387                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                 
3388                 TimeInterpolator decelerateInterpolator = (material) ? new LogDecelerateInterpolator(100,🔵
3389                 // The vertical motion of the apps panel should be delayed by one frame                  
3390                 // from the conceal animation in order to give the right feel. We correpsondingly        
3391                 // shorten the duration so that the slide and conceal end at the same time.              
3392                 ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY", 0, yDr🔵
3393                 panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3394                 panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3395                 panelDriftY.setInterpolator(decelerateInterpolator);                                     
3396                 mStateAnimation.play(panelDriftY);                                                       
3397                 ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX", 0, xDr🔵
3398                 panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                            
3399                 panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                       
3400                 panelDriftX.setInterpolator(decelerateInterpolator);                                     
3401                 mStateAnimation.play(panelDriftX);                                                       
3402                 if (isWidgetTray || (!material)) {                                                       
3403                     float finalAlpha = (material) ? 0.4F : 0.0F;                                         
3404                     revealView.setAlpha(1.0F);                                                           
3405                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha", 1.0F, fina🔵
3406                     panelAlpha.setDuration(revealDuration);                                              
3407                     panelAlpha.setInterpolator(material ? decelerateInterpolator : new AccelerateInterpol🔵
3408                     mStateAnimation.play(panelAlpha);                                                    
3409                 }                                                                                        
3410                 if (page != null) {                                                                      
3411                     page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                   
3412                     ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY", 0, yDrift)🔵
3413                     page.setTranslationY(0);                                                             
3414                     pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                          
3415                     pageDrift.setInterpolator(decelerateInterpolator);                                   
3416                     pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                     
3417                     mStateAnimation.play(pageDrift);                                                     
3418                     page.setAlpha(1.0F);                                                                 
3419                     ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1.0F, 0.0F);    
3420                     itemsAlpha.setDuration(100);                                                         
3421                     itemsAlpha.setInterpolator(decelerateInterpolator);                                  
3422                     mStateAnimation.play(itemsAlpha);                                                    
3423                 }                                                                                        
3424                 View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);         
3425                 pageIndicators.setAlpha(1.0F);                                                           
3426                 ObjectAnimator indicatorsAlpha = LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0.0F)🔵
3427                 indicatorsAlpha.setDuration(revealDuration);                                             
3428                 indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5F));                       
3429                 mStateAnimation.play(indicatorsAlpha);                                                   
3430                 width = revealView.getMeasuredWidth();                                                   
3431                 if (material) {                                                                          
3432                     if (!isWidgetTray) {                                                                 
3433                         allAppsButton.setVisibility(View.INVISIBLE);                                     
3434                     }                                                                                    
3435                     int allAppsButtonSize = LauncherAppState.getInstance().getDynamicGrid().getDeviceProf🔵
3436                     float finalRadius = (isWidgetTray) ? 0 : allAppsButtonSize / 2;                      
3437                     Animator reveal = LauncherAnimUtils.createCircularReveal(revealView, width / 2, heigh🔵
3438                     reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                       
3439                     reveal.setDuration(revealDuration);                                                  
3440                     reveal.setStartDelay(itemsAlphaStagger);                                             
3441                     reveal.addListener(new AnimatorListenerAdapter() {                                   
3442                         public void onAnimationEnd(Animator animation) {                                 
3443                             revealView.setVisibility(View.INVISIBLE);                                    
3444                             if (!isWidgetTray) {                                                         
3445                                 allAppsButton.setVisibility(View.VISIBLE);                               
3446                             }                                                                            
3447                         }                                                                                
3448                     });                                                                                  
3449                     mStateAnimation.play(reveal);                                                        
3450                 }                                                                                        
3451                 dispatchOnLauncherTransitionPrepare(fromView, animated, true);                           
3452                 dispatchOnLauncherTransitionPrepare(toView, animated, true);                             
3453                 mAppsCustomizeContent.stopScrolling();                                                   
3454             }                                                                                            
3455             mStateAnimation.addListener(new AnimatorListenerAdapter() {                                  
3456                 @Override                                                                                
3457                 public void onAnimationEnd(Animator animation) {                                         
3458                     fromView.setVisibility(View.GONE);                                                   
3459                     dispatchOnLauncherTransitionEnd(fromView, animated, true);                           
3460                     dispatchOnLauncherTransitionEnd(toView, animated, true);                             
3461                     if (onCompleteRunnable != null) {                                                    
3462                         onCompleteRunnable.run();                                                        
3463                     }                                                                                    
3464                     revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                 
3465                     if (page != null) {                                                                  
3466                         page.setLayerType(View.LAYER_TYPE_NONE, null);                                   
3467                     }                                                                                    
3468                     content.setPageBackgroundsVisible(true);                                             
3469                     // Unhide side pages                                                                 
3470                     int count = content.getChildCount();                                                 
3471                     for (int i = 0; i < count; i++) {                                                    
3472                         View child = content.getChildAt(i);                                              
3473                         child.setVisibility(View.VISIBLE);                                               
3474                     }                                                                                    
3475                     // Reset page transforms                                                             
3476                     if (page != null) {                                                                  
3477                         page.setTranslationX(0);                                                         
3478                         page.setTranslationY(0);                                                         
3479                         page.setAlpha(1);                                                                
3480                     }                                                                                    
3481                     content.setCurrentPage(content.getNextPage());                                       
3482                     mAppsCustomizeContent.updateCurrentPageScroll();                                     
3483                 }                                                                                        
3484             });                                                                                          
3485             final AnimatorSet stateAnimation = mStateAnimation;                                          
3486             final Runnable startAnimRunnable = new Runnable() {                                          
3487                 public void run() {                                                                      
3488                     // Check that mStateAnimation hasn't changed while                                   
3489                     // we waited for a layout/draw pass                                                  
3490                     if (mStateAnimation != stateAnimation) {                                             
3491                         return;                                                                          
3492                     }                                                                                    
3493                     dispatchOnLauncherTransitionStart(fromView, animated, false);                        
3494                     dispatchOnLauncherTransitionStart(toView, animated, false);                          
3495                     if (Utilities.isLmpOrAbove()) {                                                      
3496                         for (int i = 0; i < layerViews.size(); i++) {                                    
3497                             View v = layerViews.get(i);                                                  
3498                             if (v != null) {                                                             
3499                                 boolean attached = true;                                                 
3500                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {               
3501                                     attached = v.isAttachedToWindow();                                   
3502                                 }                                                                        
3503                                 if (attached) {                                                          
3504                                     v.buildLayer();                                                      
3505                                 }                                                                        
3506                             }                                                                            
3507                         }                                                                                
3508                     }                                                                                    
3509                     mStateAnimation.start();                                                             
3510                 }                                                                                        
3511             };                                                                                           
3512             fromView.post(startAnimRunnable);                                                            
3513         } else {                                                                                         
3514             fromView.setVisibility(View.GONE);                                                           
3515             dispatchOnLauncherTransitionPrepare(fromView, animated, true);                               
3516             dispatchOnLauncherTransitionStart(fromView, animated, true);                                 
3517             dispatchOnLauncherTransitionEnd(fromView, animated, true);                                   
3518             dispatchOnLauncherTransitionPrepare(toView, animated, true);                                 
3519             dispatchOnLauncherTransitionStart(toView, animated, true);                                   
3520             dispatchOnLauncherTransitionEnd(toView, animated, true);                                     
3521         }                                                                                                
3522     }                                                                                                    
3523                                                                                                          
3524     @Override                                                                                            
3525     public void onTrimMemory(int level) {                                                                
3526         super.onTrimMemory(level);                                                                       
3527         if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                         
3528             mAppsCustomizeTabHost.onTrimMemory();                                                        
3529         }                                                                                                
3530     }                                                                                                    
3531                                                                                                          
3532     protected void showWorkspace(boolean animated) {                                                     
3533         showWorkspace(animated, null);                                                                   
3534     }                                                                                                    
3535                                                                                                          
3536     protected void showWorkspace() {                                                                     
3537         showWorkspace(true);                                                                             
3538     }                                                                                                    
3539                                                                                                          
3540     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3541         if ((mState != State.WORKSPACE) || (mWorkspace.getState() != Workspace.State.NORMAL)) {          
3542             boolean wasInSpringLoadedMode = mState != State.WORKSPACE;                                   
3543             mWorkspace.setVisibility(View.VISIBLE);                                                      
3544             hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);        
3545             // Show the search bar (only animate if we were showing the drop target bar in spring        
3546             // loaded mode)                                                                              
3547             if (mSearchDropTargetBar != null) {                                                          
3548                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3549             }                                                                                            
3550             // Set focus to the AppsCustomize button                                                     
3551             if (mAllAppsButton != null) {                                                                
3552                 mAllAppsButton.requestFocus();                                                           
3553             }                                                                                            
3554         }                                                                                                
3555         // Change the state *after* we've called all the transition code                                 
3556         mState = State.WORKSPACE;                                                                        
3557         // Resume the auto-advance of widgets                                                            
3558         mUserPresent = true;                                                                             
3559         updateRunning();                                                                                 
3560         // Send an accessibility event to announce the context change                                    
3561         getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 
3562         onWorkspaceShown(animated);                                                                      
3563     }                                                                                                    
3564                                                                                                          
3565     void showOverviewMode(boolean animated) {                                                            
3566         mWorkspace.setVisibility(View.VISIBLE);                                                          
3567         hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                        
3568         mState = State.WORKSPACE;                                                                        
3569         onWorkspaceShown(animated);                                                                      
3570     }                                                                                                    
3571                                                                                                          
3572     public void onWorkspaceShown(boolean animated) {                                                     
3573     }                                                                                                    
3574                                                                                                          
3575     void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType, boolean resetPageT🔵
3576         if (mState != State.WORKSPACE) {                                                                 
3577             return;                                                                                      
3578         }                                                                                                
3579         if (resetPageToZero) {                                                                           
3580             mAppsCustomizeTabHost.reset();                                                               
3581         }                                                                                                
3582         showAppsCustomizeHelper(animated, false, contentType);                                           
3583         mAppsCustomizeTabHost.post(new Runnable() {                                                      
3584             @Override                                                                                    
3585             public void run() {                                                                          
3586                 // We post this in-case the all apps view isn't yet constructed.                         
3587                 mAppsCustomizeTabHost.requestFocus();                                                    
3588             }                                                                                            
3589         });                                                                                              
3590         // Change the state *after* we've called all the transition code                                 
3591         mState = State.APPS_CUSTOMIZE;                                                                   
3592         // Pause the auto-advance of widgets until we are out of AllApps                                 
3593         mUserPresent = false;                                                                            
3594         updateRunning();                                                                                 
3595         closeFolder();                                                                                   
3596         // Send an accessibility event to announce the context change                                    
3597         getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 
3598     }                                                                                                    
3599                                                                                                          
3600     void enterSpringLoadedDragMode() {                                                                   
3601         if (isAllAppsVisible()) {                                                                        
3602             hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                    
3603             mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                 
3604         }                                                                                                
3605     }                                                                                                    
3606                                                                                                          
3607     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay, final Runnable onComple🔵
3608         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3609             return;                                                                                      
3610         }                                                                                                
3611         mHandler.postDelayed(new Runnable() {                                                            
3612             @Override                                                                                    
3613             public void run() {                                                                          
3614                 if (successfulDrop) {                                                                    
3615                     // Before we show workspace, hide all apps again because                             
3616                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3617                     // clean up our state transition functions                                           
3618                     mAppsCustomizeTabHost.setVisibility(View.GONE);                                      
3619                     showWorkspace(true, onCompleteRunnable);                                             
3620                 } else {                                                                                 
3621                     exitSpringLoadedDragMode();                                                          
3622                 }                                                                                        
3623             }                                                                                            
3624         }, delay);                                                                                       
3625     }                                                                                                    
3626                                                                                                          
3627     void exitSpringLoadedDragMode() {                                                                    
3628         if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                              
3629             final boolean animated = true;                                                               
3630             final boolean springLoaded = true;                                                           
3631             showAppsCustomizeHelper(animated, springLoaded);                                             
3632             mState = State.APPS_CUSTOMIZE;                                                               
3633         }                                                                                                
3634         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3635     }                                                                                                    
3636                                                                                                          
3637     void lockAllApps() {                                                                                 
3638         // TODO                                                                                          
3639     }                                                                                                    
3640                                                                                                          
3641     void unlockAllApps() {                                                                               
3642         // TODO                                                                                          
3643     }                                                                                                    
3644                                                                                                          
3645     /**                                                                                                  
3646      * Hides the hotseat area.                                                                           
3647      */                                                                                                  
3648     void hideHotseat(boolean animated) {                                                                 
3649         if (!LauncherAppState.getInstance().isScreenLarge()) {                                           
3650             if (animated) {                                                                              
3651                 if (mHotseat.getAlpha() != 0f) {                                                         
3652                     int duration = 0;                                                                    
3653                     if (mSearchDropTargetBar != null) {                                                  
3654                         duration = mSearchDropTargetBar.getTransitionOutDuration();                      
3655                     }                                                                                    
3656                     mHotseat.animate().alpha(0f).setDuration(duration);                                  
3657                 }                                                                                        
3658             } else {                                                                                     
3659                 mHotseat.setAlpha(0f);                                                                   
3660             }                                                                                            
3661         }                                                                                                
3662     }                                                                                                    
3663                                                                                                          
3664     /**                                                                                                  
3665      * Add an item from all apps or customize onto the given workspace screen.                           
3666      * If layout is null, add to the current screen.                                                     
3667      */                                                                                                  
3668     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                           
3669         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                     
3670             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
3671         }                                                                                                
3672     }                                                                                                    
3673                                                                                                          
3674     /** Maps the current orientation to an index for referencing orientation correct global icons */     
3675     private int getCurrentOrientationIndexForGlobalIcons() {                                             
3676         // default - 0, landscape - 1                                                                    
3677         switch (getResources().getConfiguration().orientation) {                                         
3678         case Configuration.ORIENTATION_LANDSCAPE:                                                        
3679             return 1;                                                                                    
3680         default:                                                                                         
3681             return 0;                                                                                    
3682         }                                                                                                
3683     }                                                                                                    
3684                                                                                                          
3685     private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {    
3686         try {                                                                                            
3687             PackageManager packageManager = getPackageManager();                                         
3688             // Look for the toolbar icon specified in the activity meta-data                             
3689             Bundle metaData = packageManager.getActivityInfo(                                            
3690                     activityName, PackageManager.GET_META_DATA).metaData;                                
3691             if (metaData != null) {                                                                      
3692                 int iconResId = metaData.getInt(resourceName);                                           
3693                 if (iconResId != 0) {                                                                    
3694                     Resources res = packageManager.getResourcesForActivity(activityName);                
3695                     return res.getDrawable(iconResId);                                                   
3696                 }                                                                                        
3697             }                                                                                            
3698         } catch (NameNotFoundException e) {                                                              
3699             // This can happen if the activity defines an invalid drawable                               
3700             Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +           
3701                     " not found", e);                                                                    
3702         } catch (Resources.NotFoundException nfe) {                                                      
3703             // This can happen if the activity defines an invalid drawable                               
3704             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),        
3705                     nfe);                                                                                
3706         }                                                                                                
3707         return null;                                                                                     
3708     }                                                                                                    
3709                                                                                                          
3710     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3711     private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                         
3712             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3713             String toolbarResourceName) {                                                                
3714         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3715         Resources r = getResources();                                                                    
3716         int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                            
3717         int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                           
3718                                                                                                          
3719         TextView button = (TextView) findViewById(buttonId);                                             
3720         // If we were unable to find the icon via the meta-data, use a generic one                       
3721         if (toolbarIcon == null) {                                                                       
3722             toolbarIcon = r.getDrawable(fallbackDrawableId);                                             
3723             toolbarIcon.setBounds(0, 0, w, h);                                                           
3724             if (button != null) {                                                                        
3725                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3726             }                                                                                            
3727             return null;                                                                                 
3728         } else {                                                                                         
3729             toolbarIcon.setBounds(0, 0, w, h);                                                           
3730             if (button != null) {                                                                        
3731                 button.setCompoundDrawables(toolbarIcon, null, null, null);                              
3732             }                                                                                            
3733             return toolbarIcon.getConstantState();                                                       
3734         }                                                                                                
3735     }                                                                                                    
3736                                                                                                          
3737     // if successful in getting icon, return it; otherwise, set button to use default drawable           
3738     private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                             
3739             int buttonId, ComponentName activityName, int fallbackDrawableId,                            
3740             String toolbarResourceName) {                                                                
3741         ImageView button = (ImageView) findViewById(buttonId);                                           
3742         Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);         
3743                                                                                                          
3744         if (button != null) {                                                                            
3745             // If we were unable to find the icon via the meta-data, use a                               
3746             // generic one                                                                               
3747             if (toolbarIcon == null) {                                                                   
3748                 button.setImageResource(fallbackDrawableId);                                             
3749             } else {                                                                                     
3750                 button.setImageDrawable(toolbarIcon);                                                    
3751             }                                                                                            
3752         }                                                                                                
3753                                                                                                          
3754         return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                              
3755                                                                                                          
3756     }                                                                                                    
3757                                                                                                          
3758     private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                
3759         TextView button = (TextView) findViewById(buttonId);                                             
3760         button.setCompoundDrawables(d, null, null, null);                                                
3761     }                                                                                                    
3762                                                                                                          
3763     private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                      
3764         ImageView button = (ImageView) findViewById(buttonId);                                           
3765         button.setImageDrawable(d.newDrawable(getResources()));                                          
3766     }                                                                                                    
3767                                                                                                          
3768     private void invalidatePressedFocusedStates(View container, View button) {                           
3769         if (container instanceof HolographicLinearLayout) {                                              
3770             HolographicLinearLayout layout = (HolographicLinearLayout) container;                        
3771             layout.invalidatePressedFocusedStates();                                                     
3772         } else if (button instanceof HolographicImageView) {                                             
3773             HolographicImageView view = (HolographicImageView) button;                                   
3774             view.invalidatePressedFocusedStates();                                                       
3775         }                                                                                                
3776     }                                                                                                    
3777                                                                                                          
3778     public View getQsbBar() {                                                                            
3779         if (mQsb == null) {                                                                              
3780             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                         
3781             mSearchDropTargetBar.addView(mQsb);                                                          
3782         }                                                                                                
3783         return mQsb;                                                                                     
3784     }                                                                                                    
3785                                                                                                          
3786     protected boolean updateGlobalSearchIcon() {                                                         
3787         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
3788         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                     
3789         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
3790         final View voiceButton = findViewById(R.id.voice_button);                                        
3791                                                                                                          
3792         final SearchManager searchManager =                                                              
3793                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
3794         ComponentName activityName = searchManager.getGlobalSearchActivity();                            
3795         if (activityName != null) {                                                                      
3796             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
3797             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                           
3798                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,             
3799                     TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                  
3800             if (sGlobalSearchIcon[coi] == null) {                                                        
3801                 sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                       
3802                         R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,         
3803                         TOOLBAR_ICON_METADATA_NAME);                                                     
3804             }                                                                                            
3805                                                                                                          
3806             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);        
3807             searchButton.setVisibility(View.VISIBLE);                                                    
3808             invalidatePressedFocusedStates(searchButtonContainer, searchButton);                         
3809             return true;                                                                                 
3810         } else {                                                                                         
3811             // We disable both search and voice search when there is no global search provider           
3812             if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);           
3813             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
3814             if (searchButton != null) searchButton.setVisibility(View.GONE);                             
3815             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
3816             updateVoiceButtonProxyVisible(false);                                                        
3817             return false;                                                                                
3818         }                                                                                                
3819     }                                                                                                    
3820                                                                                                          
3821     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                    
3822         final View searchButtonContainer = findViewById(R.id.search_button_container);                   
3823         final View searchButton = (ImageView) findViewById(R.id.search_button);                          
3824         updateButtonWithDrawable(R.id.search_button, d);                                                 
3825         invalidatePressedFocusedStates(searchButtonContainer, searchButton);                             
3826     }                                                                                                    
3827                                                                                                          
3828     protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                     
3829         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
3830         final View voiceButton = findViewById(R.id.voice_button);                                        
3831                                                                                                          
3832         // We only show/update the voice search icon if the search icon is enabled as well               
3833         final SearchManager searchManager =                                                              
3834                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                
3835         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
3836                                                                                                          
3837         ComponentName activityName = null;                                                               
3838         if (globalSearchActivity != null) {                                                              
3839             // Check if the global search activity handles voice search                                  
3840             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
3841             intent.setPackage(globalSearchActivity.getPackageName());                                    
3842             activityName = intent.resolveActivity(getPackageManager());                                  
3843         }                                                                                                
3844                                                                                                          
3845         if (activityName == null) {                                                                      
3846             // Fallback: check if an activity other than the global search activity                      
3847             // resolves this                                                                             
3848             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                              
3849             activityName = intent.resolveActivity(getPackageManager());                                  
3850         }                                                                                                
3851         if (searchVisible && activityName != null) {                                                     
3852             int coi = getCurrentOrientationIndexForGlobalIcons();                                        
3853             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                            
3854                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,               
3855                     TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                            
3856             if (sVoiceSearchIcon[coi] == null) {                                                         
3857                 sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                        
3858                         R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,           
3859                         TOOLBAR_ICON_METADATA_NAME);                                                     
3860             }                                                                                            
3861             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);          
3862             voiceButton.setVisibility(View.VISIBLE);                                                     
3863             updateVoiceButtonProxyVisible(false);                                                        
3864             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                           
3865             return true;                                                                                 
3866         } else {                                                                                         
3867             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);             
3868             if (voiceButton != null) voiceButton.setVisibility(View.GONE);                               
3869             updateVoiceButtonProxyVisible(false);                                                        
3870             return false;                                                                                
3871         }                                                                                                
3872     }                                                                                                    
3873                                                                                                          
3874     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                     
3875         final View voiceButtonContainer = findViewById(R.id.voice_button_container);                     
3876         final View voiceButton = findViewById(R.id.voice_button);                                        
3877         updateButtonWithDrawable(R.id.voice_button, d);                                                  
3878         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                               
3879     }                                                                                                    
3880                                                                                                          
3881     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                    
3882         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                             
3883         if (voiceButtonProxy != null) {                                                                  
3884             boolean visible = !forceDisableVoiceButtonProxy &&                                           
3885                     mWorkspace.shouldVoiceButtonProxyBeVisible();                                        
3886             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                          
3887             voiceButtonProxy.bringToFront();                                                             
3888         }                                                                                                
3889     }                                                                                                    
3890                                                                                                          
3891     /**                                                                                                  
3892      * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button🔵
3893      * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                      
3894      */                                                                                                  
3895     public void disableVoiceButtonProxy(boolean disabled) {                                              
3896         updateVoiceButtonProxyVisible(disabled);                                                         
3897     }                                                                                                    
3898                                                                                                          
3899     @Override                                                                                            
3900     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3901         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3902         final List<CharSequence> text = event.getText();                                                 
3903         text.clear();                                                                                    
3904         // Populate event with a fake title based on the current state.                                  
3905         if (mState == State.APPS_CUSTOMIZE) {                                                            
3906             text.add(mAppsCustomizeTabHost.getContentTag());                                             
3907         } else {                                                                                         
3908             text.add(getString(R.string.all_apps_home_button_label));                                    
3909         }                                                                                                
3910         return result;                                                                                   
3911     }                                                                                                    
3912                                                                                                          
3913     /**                                                                                                  
3914      * Receives notifications when system dialogs are to be closed.                                      
3915      */                                                                                                  
3916     private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                           
3917         @Override                                                                                        
3918         public void onReceive(Context context, Intent intent) {                                          
3919             closeSystemDialogs();                                                                        
3920         }                                                                                                
3921     }                                                                                                    
3922                                                                                                          
3923     /**                                                                                                  
3924      * Receives notifications whenever the appwidgets are reset.                                         
3925      */                                                                                                  
3926     private class AppWidgetResetObserver extends ContentObserver {                                       
3927         public AppWidgetResetObserver() {                                                                
3928             super(new Handler());                                                                        
3929         }                                                                                                
3930                                                                                                          
3931         @Override                                                                                        
3932         public void onChange(boolean selfChange) {                                                       
3933             onAppWidgetReset();                                                                          
3934         }                                                                                                
3935     }                                                                                                    
3936                                                                                                          
3937     /**                                                                                                  
3938      * If the activity is currently paused, signal that we need to run the passed Runnable               
3939      * in onResume.                                                                                      
3940      *                                                                                                   
3941      * This needs to be called from incoming places where resources might have been loaded               
3942      * while we are paused.  That is becaues the Configuration might be wrong                            
3943      * when we're not running, and if it comes back to what it was when we                               
3944      * were paused, we are not restarted.                                                                
3945      *                                                                                                   
3946      * Implementation of the method from LauncherModel.Callbacks.                                        
3947      *                                                                                                   
3948      * @return true if we are currently paused.  The caller might be able to                             
3949      * skip some work in that case since we will come back again.                                        
3950      */                                                                                                  
3951     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3952         if (mPaused) {                                                                                   
3953             Log.i(TAG, "Deferring update until onResume");                                               
3954             if (deletePreviousRunnables) {                                                               
3955                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3956                 }                                                                                        
3957             }                                                                                            
3958             mBindOnResumeCallbacks.add(run);                                                             
3959             return true;                                                                                 
3960         } else {                                                                                         
3961             return false;                                                                                
3962         }                                                                                                
3963     }                                                                                                    
3964                                                                                                          
3965     private boolean waitUntilResume(Runnable run) {                                                      
3966         return waitUntilResume(run, false);                                                              
3967     }                                                                                                    
3968                                                                                                          
3969     public void addOnResumeCallback(Runnable run) {                                                      
3970         mOnResumeCallbacks.add(run);                                                                     
3971     }                                                                                                    
3972                                                                                                          
3973     /**                                                                                                  
3974      * If the activity is currently paused, signal that we need to re-run the loader                     
3975      * in onResume.                                                                                      
3976      *                                                                                                   
3977      * This needs to be called from incoming places where resources might have been loaded               
3978      * while we are paused.  That is becaues the Configuration might be wrong                            
3979      * when we're not running, and if it comes back to what it was when we                               
3980      * were paused, we are not restarted.                                                                
3981      *                                                                                                   
3982      * Implementation of the method from LauncherModel.Callbacks.                                        
3983      *                                                                                                   
3984      * @return true if we are currently paused.  The caller might be able to                             
3985      * skip some work in that case since we will come back again.                                        
3986      */                                                                                                  
3987     public boolean setLoadOnResume() {                                                                   
3988         if (mPaused) {                                                                                   
3989             Log.i(TAG, "setLoadOnResume");                                                               
3990             mOnResumeNeedsLoad = true;                                                                   
3991             return true;                                                                                 
3992         } else {                                                                                         
3993             return false;                                                                                
3994         }                                                                                                
3995     }                                                                                                    
3996                                                                                                          
3997     /**                                                                                                  
3998      * Implementation of the method from LauncherModel.Callbacks.                                        
3999      */                                                                                                  
4000     public int getCurrentWorkspaceScreen() {                                                             
4001         if (mWorkspace != null) {                                                                        
4002             return mWorkspace.getCurrentPage();                                                          
4003         } else {                                                                                         
4004             return SCREEN_COUNT / 2;                                                                     
4005         }                                                                                                
4006     }                                                                                                    
4007                                                                                                          
4008     /**                                                                                                  
4009      * Refreshes the shortcuts shown on the workspace.                                                   
4010      *                                                                                                   
4011      * Implementation of the method from LauncherModel.Callbacks.                                        
4012      */                                                                                                  
4013     public void startBinding() {                                                                         
4014         setWorkspaceLoading(true);                                                                       
4015         // If we're starting binding all over again, clear any bind calls we'd postponed in              
4016         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
4017         // from scratch again                                                                            
4018         mBindOnResumeCallbacks.clear();                                                                  
4019         // Clear the workspace because it's going to be rebound                                          
4020         mWorkspace.clearDropTargets();                                                                   
4021         mWorkspace.removeAllWorkspaceScreens();                                                          
4022         mWidgetsToAdvance.clear();                                                                       
4023         if (mHotseat != null) {                                                                          
4024             mHotseat.resetLayout();                                                                      
4025         }                                                                                                
4026     }                                                                                                    
4027                                                                                                          
4028     @Override                                                                                            
4029     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
4030         bindAddScreens(orderedScreenIds);                                                                
4031                                                                                                          
4032         // If there are no screens, we need to have an empty screen                                      
4033         if (orderedScreenIds.size() == 0) {                                                              
4034             mWorkspace.addExtraEmptyScreen();                                                            
4035         }                                                                                                
4036                                                                                                          
4037         // Create the custom content page (this call updates mDefaultScreen which calls                  
4038         // setCurrentPage() so ensure that all pages are added before calling this).                     
4039         if (hasCustomContentToLeft()) {                                                                  
4040             mWorkspace.createCustomContentContainer();                                                   
4041             populateCustomContentContainer();                                                            
4042         }                                                                                                
4043     }                                                                                                    
4044                                                                                                          
4045     @Override                                                                                            
4046     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
4047         // Log to disk                                                                                   
4048         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
4049         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
4050                 TextUtils.join(", ", orderedScreenIds), true);                                           
4051         int count = orderedScreenIds.size();                                                             
4052         for (int i = 0; i < count; i++) {                                                                
4053             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
4054         }                                                                                                
4055     }                                                                                                    
4056                                                                                                          
4057     private boolean shouldShowWeightWatcher() {                                                          
4058         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4059         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4060         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
4061                                                                                                          
4062         return show;                                                                                     
4063     }                                                                                                    
4064                                                                                                          
4065     private void toggleShowWeightWatcher() {                                                             
4066         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
4067         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
4068         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
4069                                                                                                          
4070         show = !show;                                                                                    
4071                                                                                                          
4072         SharedPreferences.Editor editor = sp.edit();                                                     
4073         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
4074         editor.commit();                                                                                 
4075                                                                                                          
4076         if (mWeightWatcher != null) {                                                                    
4077             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
4078         }                                                                                                
4079     }                                                                                                    
4080                                                                                                          
4081     public void bindAppsAdded(final ArrayList<Long> newScreens, final ArrayList<ItemInfo> addNotAnimated,🔵
4082         Runnable r = new Runnable() {                                                                    
4083             public void run() {                                                                          
4084                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
4085             }                                                                                            
4086         };                                                                                               
4087         if (waitUntilResume(r)) {                                                                        
4088             return;                                                                                      
4089         }                                                                                                
4090         // Add the new screens                                                                           
4091         if (newScreens != null) {                                                                        
4092             bindAddScreens(newScreens);                                                                  
4093         }                                                                                                
4094         // We add the items without animation on non-visible pages, and with                             
4095         // animations on the new page (which we will try and snap to).                                   
4096         if ((addNotAnimated != null) && (!addNotAnimated.isEmpty())) {                                   
4097             bindItems(addNotAnimated, 0, addNotAnimated.size(), false);                                  
4098         }                                                                                                
4099         if ((addAnimated != null) && (!addAnimated.isEmpty())) {                                         
4100             bindItems(addAnimated, 0, addAnimated.size(), true);                                         
4101         }                                                                                                
4102         // Remove the extra empty screen                                                                 
4103         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
4104         if (((!LauncherAppState.isDisableAllApps()) && (addedApps != null)) && (mAppsCustomizeContent != 🔵
4105             mAppsCustomizeContent.addApps(addedApps);                                                    
4106         }                                                                                                
4107     }                                                                                                    
4108                                                                                                          
4109     /**                                                                                                  
4110      * Bind the items start-end from the list.                                                           
4111      *                                                                                                   
4112      * Implementation of the method from LauncherModel.Callbacks.                                        
4113      */                                                                                                  
4114     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end, final bool🔵
4115         Runnable r = new Runnable() {                                                                    
4116             public void run() {                                                                          
4117                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
4118             }                                                                                            
4119         };                                                                                               
4120         if (waitUntilResume(r)) {                                                                        
4121             return;                                                                                      
4122         }                                                                                                
4123         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
4124         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
4125         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
4126         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
4127         Workspace workspace = mWorkspace;                                                                
4128         long newShortcutsScreenId = -1;                                                                  
4129         for (int i = start; i < end; i++) {                                                              
4130             final ItemInfo item = shortcuts.get(i);                                                      
4131             // Short circuit if we are loading dock items for a configuration which has no dock          
4132             if ((item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) && (mHotseat == null)) {
4133                 continue;                                                                                
4134             }                                                                                            
4135             switch (item.itemType) {                                                                     
4136                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION :                                  
4137                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT :                                     
4138                     ShortcutInfo info = ((ShortcutInfo) (item));                                         
4139                     View shortcut = createShortcut(info);                                                
4140                     /*                                                                                   
4141                      * TODO: FIX collision case                                                          
4142                      */                                                                                  
4143                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
4144                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
4145                         if ((cl != null) && cl.isOccupied(item.cellX, item.cellY)) {                     
4146                             View v = cl.getChildAt(item.cellX, item.cellY);                              
4147                             Object tag = v.getTag();                                                     
4148                             String desc = (("Collision while binding workspace item: " + item) + ". Colli🔵
4149                             if (LauncherAppState.isDogfoodBuild()) {                                     
4150                                 throw new RuntimeException(desc);                                        
4151                             } else {                                                                     
4152                                 Log.d(TAG, desc);                                                        
4153                             }                                                                            
4154                         }                                                                                
4155                     }                                                                                    
4156                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX, it🔵
4157                     if (animateIcons) {                                                                  
4158                         // Animate all the applications up now                                           
4159                         shortcut.setAlpha(0.0F);                                                         
4160                         shortcut.setScaleX(0.0F);                                                        
4161                         shortcut.setScaleY(0.0F);                                                        
4162                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
4163                         newShortcutsScreenId = item.screenId;                                            
4164                     }                                                                                    
4165                     break;                                                                               
4166                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER :                                       
4167                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, ((ViewGroup) (w🔵
4168                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX, i🔵
4169                     break;                                                                               
4170                 default :                                                                                
4171                     throw new RuntimeException("Invalid Item Type");                                     
4172             }                                                                                            
4173         }                                                                                                
4174         if (animateIcons) {                                                                              
4175             // Animate to the correct page                                                               
4176             if (newShortcutsScreenId > (-1)) {                                                           
4177                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
4178                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
4179                 final Runnable startBounceAnimRunnable = new Runnable() {                                
4180                     public void run() {                                                                  
4181                         anim.playTogether(bounceAnims);                                                  
4182                         anim.start();                                                                    
4183                     }                                                                                    
4184                 };                                                                                       
4185                 if (newShortcutsScreenId != currentScreenId) {                                           
4186                     // We post the animation slightly delayed to prevent slowdowns                       
4187                     // when we are loading right after we return to launcher.                            
4188                     mWorkspace.postDelayed(new Runnable() {                                              
4189                         public void run() {                                                              
4190                             if (mWorkspace != null) {                                                    
4191                                 mWorkspace.snapToPage(newScreenIndex);                                   
4192                                 mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY)🔵
4193                             }                                                                            
4194                         }                                                                                
4195                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
4196                 } else {                                                                                 
4197                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
4198                 }                                                                                        
4199             }                                                                                            
4200         }                                                                                                
4201         workspace.requestLayout();                                                                       
4202     }                                                                                                    
4203                                                                                                          
4204     /**                                                                                                  
4205      * Implementation of the method from LauncherModel.Callbacks.                                        
4206      */                                                                                                  
4207     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
4208         Runnable r = new Runnable() {                                                                    
4209             public void run() {                                                                          
4210                 bindFolders(folders);                                                                    
4211             }                                                                                            
4212         };                                                                                               
4213         if (waitUntilResume(r)) {                                                                        
4214             return;                                                                                      
4215         }                                                                                                
4216         sFolders.clear();                                                                                
4217         sFolders.putAll(folders);                                                                        
4218     }                                                                                                    
4219                                                                                                          
4220     /**                                                                                                  
4221      * Add the views for a widget to the workspace.                                                      
4222      *                                                                                                   
4223      * Implementation of the method from LauncherModel.Callbacks.                                        
4224      */                                                                                                  
4225     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
4226         Runnable r = new Runnable() {                                                                    
4227             public void run() {                                                                          
4228                 bindAppWidget(item);                                                                     
4229             }                                                                                            
4230         };                                                                                               
4231         if (waitUntilResume(r)) {                                                                        
4232             return;                                                                                      
4233         }                                                                                                
4234         final long start = (DEBUG_WIDGETS) ? SystemClock.uptimeMillis() : 0;                             
4235         if (DEBUG_WIDGETS) {                                                                             
4236             Log.d(TAG, "bindAppWidget: " + item);                                                        
4237         }                                                                                                
4238         final Workspace workspace = mWorkspace;                                                          
4239         AppWidgetProviderInfo appWidgetInfo;                                                             
4240         if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) && ((item.restore🔵
4241             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);      
4242             if (appWidgetInfo == null) {                                                                 
4243                 if (DEBUG_WIDGETS) {                                                                     
4244                     Log.d(TAG, ((("Removing restored widget: id=" + item.appWidgetId) + " belongs to comp🔵
4245                 }                                                                                        
4246                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4247                 return;                                                                                  
4248             }                                                                                            
4249             // Note: This assumes that the id remap broadcast is received before this step.              
4250             // If that is not the case, the id remap will be ignored and user may see the                
4251             // click to setup view.                                                                      
4252             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);      
4253             pendingInfo.spanX = item.spanX;                                                              
4254             pendingInfo.spanY = item.spanY;                                                              
4255             pendingInfo.minSpanX = item.minSpanX;                                                        
4256             pendingInfo.minSpanY = item.minSpanY;                                                        
4257             Bundle options = AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);       
4258             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
4259             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId, appWidgetInfo, opti🔵
4260             // TODO consider showing a permission dialog when the widget is clicked.                     
4261             if (!success) {                                                                              
4262                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
4263                 if (DEBUG_WIDGETS) {                                                                     
4264                     Log.d(TAG, ((("Removing restored widget: id=" + item.appWidgetId) + " belongs to comp🔵
4265                 }                                                                                        
4266                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4267                 return;                                                                                  
4268             }                                                                                            
4269             item.appWidgetId = newWidgetId;                                                              
4270             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4271             // the widget is ready to go.                                                                
4272             item.restoreStatus = (appWidgetInfo.configure == null) ? LauncherAppWidgetInfo.RESTORE_COMPLE🔵
4273             LauncherModel.updateItemInDatabase(this, item);                                              
4274         }                                                                                                
4275         if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                             
4276             final int appWidgetId = item.appWidgetId;                                                    
4277             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                             
4278             if (DEBUG_WIDGETS) {                                                                         
4279                 Log.d(TAG, (("bindAppWidget: id=" + item.appWidgetId) + " belongs to component ") + appWi🔵
4280             }                                                                                            
4281             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4282         } else {                                                                                         
4283             appWidgetInfo = null;                                                                        
4284             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                    
4285             view.updateIcon(mIconCache);                                                                 
4286             item.hostView = view;                                                                        
4287             item.hostView.updateAppWidget(null);                                                         
4288             item.hostView.setOnClickListener(this);                                                      
4289         }                                                                                                
4290         item.hostView.setTag(item);                                                                      
4291         item.onBindAppWidget(this);                                                                      
4292         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX, item.cellY, item.🔵
4293         addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                    
4294         workspace.requestLayout();                                                                       
4295         if (DEBUG_WIDGETS) {                                                                             
4296             Log.d(TAG, ((("bound widget id=" + item.appWidgetId) + " in ") + (SystemClock.uptimeMillis() 🔵
4297         }                                                                                                
4298     }                                                                                                    
4299                                                                                                          
4300     /**                                                                                                  
4301      * Restores a pending widget.                                                                        
4302      *                                                                                                   
4303      * @param appWidgetId The app widget id                                                              
4304      * @param cellInfo The position on screen where to create the widget.                                
4305      */                                                                                                  
4306     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4307         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4308         if ((view == null) || (!(view instanceof PendingAppWidgetHostView))) {                           
4309             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4310             return;                                                                                      
4311         }                                                                                                
4312         LauncherAppWidgetInfo info = ((LauncherAppWidgetInfo) (view.getTag()));                          
4313         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4314         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4315         LauncherModel.updateItemInDatabase(this, info);                                                  
4316     }                                                                                                    
4317                                                                                                          
4318     public void onPageBoundSynchronously(int page) {                                                     
4319         mSynchronouslyBoundPages.add(page);                                                              
4320     }                                                                                                    
4321                                                                                                          
4322     /**                                                                                                  
4323      * Callback saying that there aren't any more items to bind.                                         
4324      *                                                                                                   
4325      * Implementation of the method from LauncherModel.Callbacks.                                        
4326      */                                                                                                  
4327     public void finishBindingItems(final boolean upgradePath) {                                          
4328         Runnable r = new Runnable() {                                                                    
4329             public void run() {                                                                          
4330                 finishBindingItems(upgradePath);                                                         
4331             }                                                                                            
4332         };                                                                                               
4333         if (waitUntilResume(r)) {                                                                        
4334             return;                                                                                      
4335         }                                                                                                
4336         if (mSavedState != null) {                                                                       
4337             if (!mWorkspace.hasFocus()) {                                                                
4338                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4339             }                                                                                            
4340             mSavedState = null;                                                                          
4341         }                                                                                                
4342         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4343         setWorkspaceLoading(false);                                                                      
4344         sendLoadingCompleteBroadcastIfNecessary();                                                       
4345         // If we received the result of any pending adds while the loader was running (e.g. the          
4346         // widget configuration forced an orientation change), process them now.                         
4347         if (sPendingAddItem != null) {                                                                   
4348             final long screenId = completeAdd(sPendingAddItem);                                          
4349             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4350             // the screen would be guaranteed to exist after bind, and the page would be set through     
4351             // the workspace restore process.                                                            
4352             mWorkspace.post(new Runnable() {                                                             
4353                 @Override                                                                                
4354                 public void run() {                                                                      
4355                     mWorkspace.snapToScreenId(screenId);                                                 
4356                 }                                                                                        
4357             });                                                                                          
4358             sPendingAddItem = null;                                                                      
4359         }                                                                                                
4360         if (upgradePath) {                                                                               
4361             mWorkspace.getUniqueComponents(true, null);                                                  
4362             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);             
4363         }                                                                                                
4364         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4365         mModel.recheckRestoredItems(this);                                                               
4366     }                                                                                                    
4367                                                                                                          
4368     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4369         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4370             String permission = getResources().getString(R.string.receive_first_load_broadcast_permission🔵
4371             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4372             sendBroadcast(intent, permission);                                                           
4373             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4374             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4375             editor.apply();                                                                              
4376         }                                                                                                
4377     }                                                                                                    
4378                                                                                                          
4379     public boolean isAllAppsButtonRank(int rank) {                                                       
4380         if (mHotseat != null) {                                                                          
4381             return mHotseat.isAllAppsButtonRank(rank);                                                   
4382         }                                                                                                
4383         return false;                                                                                    
4384     }                                                                                                    
4385                                                                                                          
4386     private boolean canRunNewAppsAnimation() {                                                           
4387         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4388         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4389     }                                                                                                    
4390                                                                                                          
4391     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4392         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4393                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4394                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4395                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4396         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4397         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4398         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4399         return bounceAnim;                                                                               
4400     }                                                                                                    
4401                                                                                                          
4402     public boolean useVerticalBarLayout() {                                                              
4403         return LauncherAppState.getInstance().getDynamicGrid().                                          
4404                 getDeviceProfile().isVerticalBarLayout();                                                
4405     }                                                                                                    
4406                                                                                                          
4407     protected Rect getSearchBarBounds() {                                                                
4408         return LauncherAppState.getInstance().getDynamicGrid().                                          
4409                 getDeviceProfile().getSearchBarBounds();                                                 
4410     }                                                                                                    
4411                                                                                                          
4412     @Override                                                                                            
4413     public void bindSearchablesChanged() {                                                               
4414         boolean searchVisible = updateGlobalSearchIcon();                                                
4415         boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                     
4416         if (mSearchDropTargetBar != null) {                                                              
4417             mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                   
4418         }                                                                                                
4419     }                                                                                                    
4420                                                                                                          
4421     /**                                                                                                  
4422      * Add the icons for all apps.                                                                       
4423      *                                                                                                   
4424      * Implementation of the method from LauncherModel.Callbacks.                                        
4425      */                                                                                                  
4426     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4427         if (LauncherAppState.isDisableAllApps()) {                                                       
4428             if (mIntentsOnWorkspaceFromUpgradePath != null) {                                            
4429                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                        
4430                     getHotseat().addAllAppsFolder(mIconCache, apps,                                      
4431                             mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);              
4432                 }                                                                                        
4433                 mIntentsOnWorkspaceFromUpgradePath = null;                                               
4434             }                                                                                            
4435             if (mAppsCustomizeContent != null) {                                                         
4436                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4437                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4438             }                                                                                            
4439         } else {                                                                                         
4440             if (mAppsCustomizeContent != null) {                                                         
4441                 mAppsCustomizeContent.setApps(apps);                                                     
4442                 mAppsCustomizeContent.onPackagesUpdated(                                                 
4443                         LauncherModel.getSortedWidgetsAndShortcuts(this));                               
4444             }                                                                                            
4445         }                                                                                                
4446     }                                                                                                    
4447                                                                                                          
4448     /**                                                                                                  
4449      * A package was updated.                                                                            
4450      *                                                                                                   
4451      * Implementation of the method from LauncherModel.Callbacks.                                        
4452      */                                                                                                  
4453     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4454         Runnable r = new Runnable() {                                                                    
4455             public void run() {                                                                          
4456                 bindAppsUpdated(apps);                                                                   
4457             }                                                                                            
4458         };                                                                                               
4459         if (waitUntilResume(r)) {                                                                        
4460             return;                                                                                      
4461         }                                                                                                
4462         if (mWorkspace != null) {                                                                        
4463             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4464         }                                                                                                
4465         if ((!LauncherAppState.isDisableAllApps()) && (mAppsCustomizeContent != null)) {                 
4466             mAppsCustomizeContent.updateApps(apps);                                                      
4467         }                                                                                                
4468     }                                                                                                    
4469                                                                                                          
4470     /**                                                                                                  
4471      * Packages were restored                                                                            
4472      */                                                                                                  
4473     public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                        
4474         Runnable r = new Runnable() {                                                                    
4475             public void run() {                                                                          
4476                 bindAppsRestored(apps);                                                                  
4477             }                                                                                            
4478         };                                                                                               
4479         if (waitUntilResume(r)) {                                                                        
4480             return;                                                                                      
4481         }                                                                                                
4482                                                                                                          
4483         if (mWorkspace != null) {                                                                        
4484             mWorkspace.updateShortcutsAndWidgets(apps);                                                  
4485         }                                                                                                
4486     }                                                                                                    
4487                                                                                                          
4488     /**                                                                                                  
4489      * Update the state of a package, typically related to install state.                                
4490      *                                                                                                   
4491      * Implementation of the method from LauncherModel.Callbacks.                                        
4492      */                                                                                                  
4493     @Override                                                                                            
4494     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4495         if (mWorkspace != null) {                                                                        
4496             mWorkspace.updatePackageState(installInfo);                                                  
4497         }                                                                                                
4498     }                                                                                                    
4499                                                                                                          
4500     /**                                                                                                  
4501      * Update the label and icon of all the icons in a package                                           
4502      *                                                                                                   
4503      * Implementation of the method from LauncherModel.Callbacks.                                        
4504      */                                                                                                  
4505     @Override                                                                                            
4506     public void updatePackageBadge(String packageName) {                                                 
4507         if (mWorkspace != null) {                                                                        
4508             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4509         }                                                                                                
4510     }                                                                                                    
4511                                                                                                          
4512     /**                                                                                                  
4513      * A package was uninstalled.  We take both the super set of packageNames                            
4514      * in addition to specific applications to remove, the reason being that                             
4515      * this can be called when a package is updated as well.  In that scenario,                          
4516      * we only remove specific components from the workspace, where as                                   
4517      * package-removal should clear all items by package name.                                           
4518      *                                                                                                   
4519      * Implementation of the method from LauncherModel.Callbacks.                                        
4520      */                                                                                                  
4521     public void bindComponentsRemoved(final ArrayList<String> packageNames, final ArrayList<AppInfo> appI🔵
4522         Runnable r = new Runnable() {                                                                    
4523             public void run() {                                                                          
4524                 bindComponentsRemoved(packageNames, appInfos, user);                                     
4525             }                                                                                            
4526         };                                                                                               
4527         if (waitUntilResume(r)) {                                                                        
4528             return;                                                                                      
4529         }                                                                                                
4530         if (!packageNames.isEmpty()) {                                                                   
4531             mWorkspace.removeItemsByPackageName(packageNames, user);                                     
4532         }                                                                                                
4533         if (!appInfos.isEmpty()) {                                                                       
4534             mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                     
4535         }                                                                                                
4536         // Notify the drag controller                                                                    
4537         mDragController.onAppsRemoved(packageNames, appInfos);                                           
4538         // Update AllApps                                                                                
4539         if ((!LauncherAppState.isDisableAllApps()) && (mAppsCustomizeContent != null)) {                 
4540             mAppsCustomizeContent.removeApps(appInfos);                                                  
4541         }                                                                                                
4542     }                                                                                                    
4543                                                                                                          
4544     /**                                                                                                  
4545      * A number of packages were updated.                                                                
4546      */                                                                                                  
4547     private ArrayList<Object> mWidgetsAndShortcuts;                                                      
4548                                                                                                          
4549     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4550             public void run() {                                                                          
4551                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4552                 mWidgetsAndShortcuts = null;                                                             
4553             }                                                                                            
4554         };                                                                                               
4555                                                                                                          
4556     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4557         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4558             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4559             return;                                                                                      
4560         }                                                                                                
4561                                                                                                          
4562         // Update the widgets pane                                                                       
4563         if (mAppsCustomizeContent != null) {                                                             
4564             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                
4565         }                                                                                                
4566     }                                                                                                    
4567                                                                                                          
4568     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4569         final Display d = getWindowManager().getDefaultDisplay();                                        
4570         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4571         switch (d.getRotation()) {                                                                       
4572         case Surface.ROTATION_0:                                                                         
4573         case Surface.ROTATION_180:                                                                       
4574             // We are currently in the same basic orientation as the natural orientation                 
4575             naturalOri = configOri;                                                                      
4576             break;                                                                                       
4577         case Surface.ROTATION_90:                                                                        
4578         case Surface.ROTATION_270:                                                                       
4579             // We are currently in the other basic orientation to the natural orientation                
4580             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4581                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4582             break;                                                                                       
4583         }                                                                                                
4584                                                                                                          
4585         int[] oriMap = {                                                                                 
4586                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4587                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4588                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4589                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4590         };                                                                                               
4591         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4592         // is landscape.                                                                                 
4593         int indexOffset = 0;                                                                             
4594         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4595             indexOffset = 1;                                                                             
4596         }                                                                                                
4597         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4598     }                                                                                                    
4599                                                                                                          
4600     public boolean isRotationEnabled() {                                                                 
4601         boolean enableRotation = sForceEnableRotation ||                                                 
4602                 getResources().getBoolean(R.bool.allow_rotation);                                        
4603         return enableRotation;                                                                           
4604     }                                                                                                    
4605                                                                                                          
4606     public void lockScreenOrientation() {                                                                
4607         if (isRotationEnabled()) {                                                                       
4608             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                    
4609                     .getConfiguration().orientation));                                                   
4610         }                                                                                                
4611     }                                                                                                    
4612                                                                                                          
4613     public void unlockScreenOrientation(boolean immediate) {                                             
4614         if (isRotationEnabled()) {                                                                       
4615             if (immediate) {                                                                             
4616                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4617             } else {                                                                                     
4618                 mHandler.postDelayed(new Runnable() {                                                    
4619                     public void run() {                                                                  
4620                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4621                     }                                                                                    
4622                 }, mRestoreScreenOrientationDelay);                                                      
4623             }                                                                                            
4624         }                                                                                                
4625     }                                                                                                    
4626                                                                                                          
4627     /**                                                                                                  
4628      * Called when the SearchBar hint should be changed.                                                 
4629      *                                                                                                   
4630      * @param hint the hint to be displayed in the search bar.                                           
4631      */                                                                                                  
4632     protected void onSearchBarHintChanged(String hint) {                                                 
4633     }                                                                                                    
4634                                                                                                          
4635     protected boolean isLauncherPreinstalled() {                                                         
4636         PackageManager pm = getPackageManager();                                                         
4637         try {                                                                                            
4638             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4639             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4640                 return true;                                                                             
4641             } else {                                                                                     
4642                 return false;                                                                            
4643             }                                                                                            
4644         } catch (NameNotFoundException e) {                                                              
4645             e.printStackTrace();                                                                         
4646             return false;                                                                                
4647         }                                                                                                
4648     }                                                                                                    
4649                                                                                                          
4650     /**                                                                                                  
4651      * This method indicates whether or not we should suggest default wallpaper dimensions               
4652      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4653      */                                                                                                  
4654     protected boolean overrideWallpaperDimensions() {                                                    
4655         return true;                                                                                     
4656     }                                                                                                    
4657                                                                                                          
4658     protected boolean shouldClingFocusHotseatApp() {                                                     
4659         return false;                                                                                    
4660     }                                                                                                    
4661                                                                                                          
4662     protected String getFirstRunClingSearchBarHint() {                                                   
4663         return "";                                                                                       
4664     }                                                                                                    
4665                                                                                                          
4666     protected String getFirstRunCustomContentHint() {                                                    
4667         return "";                                                                                       
4668     }                                                                                                    
4669                                                                                                          
4670     protected int getFirstRunFocusedHotseatAppDrawableId() {                                             
4671         return -1;                                                                                       
4672     }                                                                                                    
4673                                                                                                          
4674     protected ComponentName getFirstRunFocusedHotseatAppComponentName() {                                
4675         return null;                                                                                     
4676     }                                                                                                    
4677                                                                                                          
4678     protected int getFirstRunFocusedHotseatAppRank() {                                                   
4679         return -1;                                                                                       
4680     }                                                                                                    
4681                                                                                                          
4682     protected String getFirstRunFocusedHotseatAppBubbleTitle() {                                         
4683         return "";                                                                                       
4684     }                                                                                                    
4685                                                                                                          
4686     protected String getFirstRunFocusedHotseatAppBubbleDescription() {                                   
4687         return "";                                                                                       
4688     }                                                                                                    
4689                                                                                                          
4690     /**                                                                                                  
4691      * To be overridden by subclasses to indicate that there is an activity to launch                    
4692      * before showing the standard launcher experience.                                                  
4693      */                                                                                                  
4694     protected boolean hasFirstRunActivity() {                                                            
4695         return false;                                                                                    
4696     }                                                                                                    
4697                                                                                                          
4698     /**                                                                                                  
4699      * To be overridden by subclasses to launch any first run activity                                   
4700      */                                                                                                  
4701     protected Intent getFirstRunActivity() {                                                             
4702         return null;                                                                                     
4703     }                                                                                                    
4704                                                                                                          
4705     private boolean shouldRunFirstRunActivity() {                                                        
4706         return !ActivityManager.isRunningInTestHarness() &&                                              
4707                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4708     }                                                                                                    
4709                                                                                                          
4710     protected boolean hasRunFirstRunActivity() {                                                         
4711         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4712     }                                                                                                    
4713                                                                                                          
4714     public boolean showFirstRunActivity() {                                                              
4715         if (shouldRunFirstRunActivity() && hasFirstRunActivity()) {                                      
4716             Intent firstRunIntent = getFirstRunActivity();                                               
4717             if (firstRunIntent != null) {                                                                
4718                 startActivity(firstRunIntent);                                                           
4719                 markFirstRunActivityShown();                                                             
4720                 return true;                                                                             
4721             }                                                                                            
4722         }                                                                                                
4723         return false;                                                                                    
4724     }                                                                                                    
4725                                                                                                          
4726     private void markFirstRunActivityShown() {                                                           
4727         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4728         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4729         editor.apply();                                                                                  
4730     }                                                                                                    
4731                                                                                                          
4732     /**                                                                                                  
4733      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4734      * screen that must be displayed and dismissed.                                                      
4735      */                                                                                                  
4736     protected boolean hasDismissableIntroScreen() {                                                      
4737         return false;                                                                                    
4738     }                                                                                                    
4739                                                                                                          
4740     /**                                                                                                  
4741      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4742      */                                                                                                  
4743     protected View getIntroScreen() {                                                                    
4744         return null;                                                                                     
4745     }                                                                                                    
4746                                                                                                          
4747     /**                                                                                                  
4748      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4749      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4750      */                                                                                                  
4751     private boolean shouldShowIntroScreen() {                                                            
4752         return hasDismissableIntroScreen() &&                                                            
4753                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4754     }                                                                                                    
4755                                                                                                          
4756     protected void showIntroScreen() {                                                                   
4757         View introScreen = getIntroScreen();                                                             
4758         changeWallpaperVisiblity(false);                                                                 
4759         if (introScreen != null) {                                                                       
4760             mDragLayer.showOverlayView(introScreen);                                                     
4761         }                                                                                                
4762     }                                                                                                    
4763                                                                                                          
4764     public void dismissIntroScreen() {                                                                   
4765         markIntroScreenDismissed();                                                                      
4766         if (showFirstRunActivity()) {                                                                    
4767             // We delay hiding the intro view until the first run activity is showing. This              
4768             // avoids a blip.                                                                            
4769             mWorkspace.postDelayed(new Runnable() {                                                      
4770                 @Override                                                                                
4771                 public void run() {                                                                      
4772                     mDragLayer.dismissOverlayView();                                                     
4773                     showFirstRunClings();                                                                
4774                 }                                                                                        
4775             }, ACTIVITY_START_DELAY);                                                                    
4776         } else {                                                                                         
4777             mDragLayer.dismissOverlayView();                                                             
4778             showFirstRunClings();                                                                        
4779         }                                                                                                
4780         changeWallpaperVisiblity(true);                                                                  
4781     }                                                                                                    
4782                                                                                                          
4783     private void markIntroScreenDismissed() {                                                            
4784         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4785         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4786         editor.apply();                                                                                  
4787     }                                                                                                    
4788                                                                                                          
4789     private void showFirstRunClings() {                                                                  
4790         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4791         // on the device, then we always show the first run cling experience (or if there is no          
4792         // launcher2). Otherwise, we prompt the user upon started for migration                          
4793         LauncherClings launcherClings = new LauncherClings(this);                                        
4794         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4795             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4796                 launcherClings.showMigrationCling();                                                     
4797             } else {                                                                                     
4798                 launcherClings.showLongPressCling(true);                                                 
4799             }                                                                                            
4800         }                                                                                                
4801     }                                                                                                    
4802                                                                                                          
4803     void showWorkspaceSearchAndHotseat() {                                                               
4804         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4805         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4806         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4807         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4808     }                                                                                                    
4809                                                                                                          
4810     void hideWorkspaceSearchAndHotseat() {                                                               
4811         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4812         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4813         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4814         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4815     }                                                                                                    
4816                                                                                                          
4817     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4818         // Called from search suggestion, not supported in other profiles.                               
4819         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4820         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4821         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent, myUser); 
4822         if (activityInfo == null) {                                                                      
4823             return null;                                                                                 
4824         }                                                                                                
4825         return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                
4826     }                                                                                                    
4827                                                                                                          
4828     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption, Bitmap icon) {   
4829         // Called from search suggestion, not supported in other profiles.                               
4830         return createShortcutDragInfo(shortcutIntent, caption, icon, UserHandleCompat.myUserHandle());   
4831     }                                                                                                    
4832                                                                                                          
4833     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4834             Bitmap icon, UserHandleCompat user) {                                                        
4835         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4836         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4837         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4838     }                                                                                                    
4839                                                                                                          
4840     protected void moveWorkspaceToDefaultScreen() {                                                      
4841         mWorkspace.moveToDefaultScreen(false);                                                           
4842     }                                                                                                    
4843                                                                                                          
4844     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4845         dragView.setTag(dragInfo);                                                                       
4846         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4847         mWorkspace.beginExternalDragShared(dragView, source);                                            
4848     }                                                                                                    
4849                                                                                                          
4850     @Override                                                                                            
4851     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4852     }                                                                                                    
4853                                                                                                          
4854     /**                                                                                                  
4855      * Prints out out state for debugging.                                                               
4856      */                                                                                                  
4857     public void dumpState() {                                                                            
4858         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4859         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4860         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4861         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4862         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4863         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4864         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4865         mModel.dumpState();                                                                              
4866                                                                                                          
4867         if (mAppsCustomizeContent != null) {                                                             
4868             mAppsCustomizeContent.dumpState();                                                           
4869         }                                                                                                
4870         Log.d(TAG, "END launcher3 dump state");                                                          
4871     }                                                                                                    
4872                                                                                                          
4873     @Override                                                                                            
4874     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4875         super.dump(prefix, fd, writer, args);                                                            
4876         synchronized (sDumpLogs) {                                                                       
4877             writer.println(" ");                                                                         
4878             writer.println("Debug logs: ");                                                              
4879             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4880                 writer.println("  " + sDumpLogs.get(i));                                                 
4881             }                                                                                            
4882         }                                                                                                
4883     }                                                                                                    
4884                                                                                                          
4885     public static void dumpDebugLogsToConsole() {                                                        
4886         if (DEBUG_DUMP_LOG) {                                                                            
4887             synchronized (sDumpLogs) {                                                                   
4888                 Log.d(TAG, "");                                                                          
4889                 Log.d(TAG, "*********************");                                                     
4890                 Log.d(TAG, "Launcher debug logs: ");                                                     
4891                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4892                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4893                 }                                                                                        
4894                 Log.d(TAG, "*********************");                                                     
4895                 Log.d(TAG, "");                                                                          
4896             }                                                                                            
4897         }                                                                                                
4898     }                                                                                                    
4899                                                                                                          
4900     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4901         addDumpLog(tag, log, null, debugLog);                                                            
4902     }                                                                                                    
4903                                                                                                          
4904     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4905         if (debugLog) {                                                                                  
4906             if (e != null) {                                                                             
4907                 Log.d(tag, log, e);                                                                      
4908             } else {                                                                                     
4909                 Log.d(tag, log);                                                                         
4910             }                                                                                            
4911         }                                                                                                
4912         if (DEBUG_DUMP_LOG) {                                                                            
4913             sDateStamp.setTime(System.currentTimeMillis());                                              
4914             synchronized (sDumpLogs) {                                                                   
4915                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4916                     + (e == null ? "" : (", Exception: " + e)));                                         
4917             }                                                                                            
4918         }                                                                                                
4919     }                                                                                                    
4920                                                                                                          
4921     public void dumpLogsToLocalData() {                                                                  
4922         if (DEBUG_DUMP_LOG) {                                                                            
4923             new AsyncTask<Void, Void, Void>() {                                                          
4924                 public Void doInBackground(Void ... args) {                                              
4925                     boolean success = false;                                                             
4926                     sDateStamp.setTime(sRunStart);                                                       
4927                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4928                             + sDateStamp.getDay() + "_"                                                  
4929                             + sDateStamp.getHours() + "-"                                                
4930                             + sDateStamp.getMinutes() + "_"                                              
4931                             + sDateStamp.getSeconds() + ".txt";                                          
4932                                                                                                          
4933                     FileOutputStream fos = null;                                                         
4934                     File outFile = null;                                                                 
4935                     try {                                                                                
4936                         outFile = new File(getFilesDir(), FILENAME);                                     
4937                         outFile.createNewFile();                                                         
4938                         fos = new FileOutputStream(outFile);                                             
4939                     } catch (Exception e) {                                                              
4940                         e.printStackTrace();                                                             
4941                     }                                                                                    
4942                     if (fos != null) {                                                                   
4943                         PrintWriter writer = new PrintWriter(fos);                                       
4944                                                                                                          
4945                         writer.println(" ");                                                             
4946                         writer.println("Debug logs: ");                                                  
4947                         synchronized (sDumpLogs) {                                                       
4948                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4949                                 writer.println("  " + sDumpLogs.get(i));                                 
4950                             }                                                                            
4951                         }                                                                                
4952                         writer.close();                                                                  
4953                     }                                                                                    
4954                     try {                                                                                
4955                         if (fos != null) {                                                               
4956                             fos.close();                                                                 
4957                             success = true;                                                              
4958                         }                                                                                
4959                     } catch (IOException e) {                                                            
4960                         e.printStackTrace();                                                             
4961                     }                                                                                    
4962                     return null;                                                                         
4963                 }                                                                                        
4964             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4965         }                                                                                                
4966     }                                                                                                    
4967 }                                                                                                        
4968                                                                                                          
4969 interface LauncherTransitionable {                                                                       
4970     public abstract View getContent();                                                                   
4971                                                                                                          
4972     public abstract void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace); 
4973                                                                                                          
4974     public abstract void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);   
4975                                                                                                          
4976     public abstract void onLauncherTransitionStep(Launcher l, float t);                                  
4977                                                                                                          
4978     public abstract void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);     
4979 }                                                                                                        
































































































































































































































































































































































































































































































































































































































































































































































































































ours vs. base theirs vs. base
   1                                                                                                                    
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25 +import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27 -import android.animation.ValueAnimator.AnimatorUpdateListener;                                                    
  28 +import android.annotation.TargetApi;                                                                              
  29  import android.app.Activity;                                                                                      
  30  import android.app.ActivityManager;                                                                               
  31  import android.app.ActivityOptions;                                                                               
  32 +import android.app.AlertDialog;                                                                                   
  33  import android.app.SearchManager;                                                                                 
  34  import android.appwidget.AppWidgetHostView;                                                                       
  35  import android.appwidget.AppWidgetManager;                                                                        
  36  import android.appwidget.AppWidgetProviderInfo;                                                                   
  37  import android.content.ActivityNotFoundException;                                                                 
  38  import android.content.BroadcastReceiver;                                                                         
  39  import android.content.ComponentCallbacks2;                                                                       
  40  import android.content.ComponentName;                                                                             
  41  import android.content.ContentResolver;                                                                           
  42  import android.content.Context;                                                                                   
  43 +import android.content.DialogInterface;                                                                           
  44  import android.content.Intent;                                                                                    
  45  import android.content.IntentFilter;                                                                              
  46  import android.content.SharedPreferences;                                                                         
  47  import android.content.pm.ActivityInfo;                                                                           
  48  import android.content.pm.ApplicationInfo;                                                                        
  49  import android.content.pm.PackageManager;                                                                         
  50  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  51 -import android.content.pm.ResolveInfo;                                                                            
  52  import android.content.res.Configuration;                                                                         
  53  import android.content.res.Resources;                                                                             
  54  import android.database.ContentObserver;                                                                          
  55  import android.graphics.Bitmap;                                                                                   
  56  import android.graphics.Canvas;                                                                                   
  57 +import android.graphics.Color;                                                                                    
  58  import android.graphics.Point;                                                                                    
  59  import android.graphics.PorterDuff;                                                                               
  60  import android.graphics.Rect;                                                                                     
  61  import android.graphics.drawable.Drawable;                                                                        
  62  import android.net.Uri;                                                                                           
  63  import android.os.AsyncTask;                                                                                      
  64 +import android.os.Build;                                                                                          
  65  import android.os.Bundle;                                                                                         
  66  import android.os.Environment;                                                                                    
  67  import android.os.Handler;                                                                                        
  68  import android.os.Message;                                                                                        
  69  import android.os.StrictMode;                                                                                     
  70  import android.os.SystemClock;                                                                                    
  71 -import android.provider.Settings;                                                                                 
  72  import android.speech.RecognizerIntent;                                                                           
  73  import android.text.Selection;                                                                                    
  74  import android.text.SpannableStringBuilder;                                                                       
  75  import android.text.TextUtils;                                                                                    
  76  import android.text.method.TextKeyListener;                                                                       
  77  import android.util.DisplayMetrics;                                                                               
  78  import android.util.Log;                                                                                          
  79 +import android.view.ContextThemeWrapper;                                                                          
  80  import android.view.Display;                                                                                      
  81  import android.view.Gravity;                                                                                      
  82  import android.view.HapticFeedbackConstants;                                                                      
  83  import android.view.KeyEvent;                                                                                     
  84  import android.view.LayoutInflater;                                                                               
  85  import android.view.Menu;                                                                                         
  86  import android.view.MotionEvent;                                                                                  
  87  import android.view.Surface;                                                                                      
  88  import android.view.View;                                                                                         
  89  import android.view.View.OnClickListener;                                                                         
  90  import android.view.View.OnLongClickListener;                                                                     
  91 +import android.view.ViewAnimationUtils;                                                                           
  92  import android.view.ViewGroup;                                                                                    
  93  import android.view.ViewTreeObserver;                                                                             
  94  import android.view.ViewTreeObserver.OnGlobalLayoutListener;                                                      
  95 +import android.view.Window;                                                                                       
  96  import android.view.WindowManager;                                                                                
  97  import android.view.accessibility.AccessibilityEvent;                                                             
  98 -import android.view.animation.AccelerateDecelerateInterpolator;                                                   
  99 +import android.view.animation.AccelerateInterpolator;                                                             
 100  import android.view.animation.DecelerateInterpolator;                                                             
 101 +import android.view.animation.Interpolator;                                                                       
 102  import android.view.inputmethod.InputMethodManager;                                                               
 103  import android.widget.Advanceable;                                                                                
 104  import android.widget.FrameLayout;                                                                                
 105  import android.widget.ImageView;                                                                                  
 106  import android.widget.TextView;                                                                                   
 107  import android.widget.Toast;                                                                                      
 108                                                                                                                    
 109  import com.android.launcher3.DropTarget.DragObject;                                                               
 110 +import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 111 +import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 112 +import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 113 +import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 114 +import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 115 +import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 116 +import com.android.launcher3.compat.UserHandleCompat;                                                             
 117 +import com.android.launcher3.compat.UserManagerCompat;                                                            
 118                                                                                                                    
 119  import java.io.DataInputStream;                                                                                   
 120  import java.io.DataOutputStream;                                                                                  
 121  import java.io.File;                                                                                              
 122  import java.io.FileDescriptor;                                                                                    
 123  import java.io.FileNotFoundException;                                                                             
 124  import java.io.FileOutputStream;                                                                                  
 125  import java.io.IOException;                                                                                       
 126  import java.io.PrintWriter;                                                                                       
 127 +import java.lang.reflect.Field;                                                                                   
 128 +import java.lang.reflect.InvocationTargetException;                                                               
 129 +import java.lang.reflect.Method;                                                                                  
 130  import java.text.DateFormat;                                                                                      
 131  import java.util.ArrayList;                                                                                       
 132  import java.util.Collection;                                                                                      
 133  import java.util.Date;                                                                                            
 134  import java.util.HashMap;                                                                                         
 135  import java.util.List;                                                                                            
 136  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 137                                                                                                                    
 138 -                                                                                                                  
 139  /**                                                                                                               
 140   * Default launcher application.                                                                                  
 141   */                                                                                                               
 142  public class Launcher extends Activity                                                                            
 143          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 144 -                   View.OnTouchListener {                                                                         
 145 +                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     
 146      static final String TAG = "Launcher";                                                                         
 147      static final boolean LOGD = false;                                                                            
 148                                                                                                                    
 149      static final boolean PROFILE_STARTUP = false;                                                                 
 150      static final boolean DEBUG_WIDGETS = false;                                                                   
 151      static final boolean DEBUG_STRICT_MODE = false;                                                               
 152      static final boolean DEBUG_RESUME_TIME = false;                                                               
 153      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 154                                                                                                                    
 155      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 156                                                                                                                    
 157      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 158      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 159 -    private static final int REQUEST_PICK_APPLICATION = 6;                                                        
 160      private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 161      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 162      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 163                                                                                                                    
 164      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 165 +    private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 166                                                                                                                    
 167      /**                                                                                                           
 168       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 169       * request codes used internally.                                                                             
 170       */                                                                                                           
 171      protected static final int REQUEST_LAST = 100;                                                                
 172                                                                                                                    
 173      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 174                                                                                                                    
 175      static final int SCREEN_COUNT = 5;                                                                            
 176      static final int DEFAULT_SCREEN = 2;                                                                          
 177                                                                                                                    
 178      private static final String PREFERENCES = "launcher.preferences";                                             
 179      // To turn on these properties, type                                                                          
 180      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 181      static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";                                 
 182      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 183      static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 184                                                                                                                    
 185      // The Intent extra that defines whether to ignore the launch animation                                       
 186      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 187              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 188                                                                                                                    
 189      // Type: int                                                                                                  
 190      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 191      // Type: int                                                                                                  
 192      private static final String RUNTIME_STATE = "launcher.state";                                                 
 193      // Type: int                                                                                                  
 194      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 195      // Type: int                                                                                                  
 196      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 197      // Type: int                                                                                                  
 198      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 199      // Type: int                                                                                                  
 200      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 201      // Type: boolean                                                                                              
 202      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 203      // Type: long                                                                                                 
 204      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 205      // Type: int                                                                                                  
 206      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 207      // Type: int                                                                                                  
 208      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 209      // Type: parcelable                                                                                           
 210      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 211      // Type: parcelable                                                                                           
 212      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 213      // Type: int[]                                                                                                
 214      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 215                                                                                                                    
 216 -                                                                                                                  
 217 +    static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 218      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 219 +                                                                                                                  
 220 +    static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 221 +    static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 222 +            "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 223                                                                                                                    
 224      private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";                 
 225      private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =                                               
 226              "com.android.launcher.toolbar_search_icon";                                                           
 227      private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =                                         
 228              "com.android.launcher.toolbar_voice_search_icon";                                                     
 229                                                                                                                    
 230      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 231      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 232                                                                                                                    
 233      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 234                                                                                                                    
 235      /** The different states that Launcher can be in. */                                                          
 236      private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 237      private State mState = State.WORKSPACE;                                                                       
 238      private AnimatorSet mStateAnimation;                                                                          
 239                                                                                                                    
 240 +    private boolean mIsSafeModeEnabled;                                                                           
 241 +                                                                                                                  
 242      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 243      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 244 -    public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT_FOLDER_CLOSE = 400;                              
 245      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 246 +    private static final int ACTIVITY_START_DELAY = 1000;                                                         
 247                                                                                                                    
 248      private static final Object sLock = new Object();                                                             
 249      private static int sScreen = DEFAULT_SCREEN;                                                                  
 250                                                                                                                    
 251      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 252      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 253                                                                                                                    
 254      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 255      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 256      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 257      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 258 +    private static final int SINGLE_FRAME_DELAY = 16;                                                             
 259                                                                                                                    
 260      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 261              = new CloseSystemDialogsIntentReceiver();                                                             
 262      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 263                                                                                                                    
 264      private LayoutInflater mInflater;                                                                             
 265                                                                                                                    
 266      private Workspace mWorkspace;                                                                                 
 267      private View mLauncherView;                                                                                   
 268      private View mPageIndicators;                                                                                 
 269      private DragLayer mDragLayer;                                                                                 
 270      private DragController mDragController;                                                                       
 271      private View mWeightWatcher;                                                                                  
 272 -    private LauncherClings mLauncherClings;                                                                       
 273 -                                                                                                                  
 274 -    private AppWidgetManager mAppWidgetManager;                                                                   
 275 +                                                                                                                  
 276 +    private AppWidgetManagerCompat mAppWidgetManager;                                                             
 277      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 278                                                                                                                    
 279      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 280      private AppWidgetProviderInfo mPendingAddWidgetInfo;                                                          
 281      private int mPendingAddWidgetId = -1;                                                                         
 282                                                                                                                    
 283      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 284                                                                                                                    
 285      private FolderInfo mFolderInfo;                                                                               
 286                                                                                                                    
 287      private Hotseat mHotseat;                                                                                     
 288      private ViewGroup mOverviewPanel;                                                                             
 289                                                                                                                    
 290      private View mAllAppsButton;                                                                                  
 291                                                                                                                    
 292      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 293      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 294      private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 295      private boolean mAutoAdvanceRunning = false;                                                                  
 296      private View mQsb;                                                                                            
 297                                                                                                                    
 298      private Bundle mSavedState;                                                                                   
 299      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 300      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 301      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 302      private State mOnResumeState = State.NONE;                                                                    
 303                                                                                                                    
 304      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 305                                                                                                                    
 306      private boolean mWorkspaceLoading = true;                                                                     
 307                                                                                                                    
 308      private boolean mPaused = true;                                                                               
 309      private boolean mRestoring;                                                                                   
 310      private boolean mWaitingForResult;                                                                            
 311      private boolean mOnResumeNeedsLoad;                                                                           
 312                                                                                                                    
 313      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 314      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 315 -                                                                                                                  
 316 -    // Keep track of whether the user has left launcher                                                           
 317 -    private static boolean sPausedFromUserAction = false;                                                         
 318                                                                                                                    
 319      private Bundle mSavedInstanceState;                                                                           
 320                                                                                                                    
 321      private LauncherModel mModel;                                                                                 
 322      private IconCache mIconCache;                                                                                 
 323      private boolean mUserPresent = true;                                                                          
 324      private boolean mVisible = false;                                                                             
 325      private boolean mHasFocus = false;                                                                            
 326      private boolean mAttached = false;                                                                            
 327                                                                                                                    
 328      private static LocaleConfiguration sLocaleConfiguration = null;                                               
 329                                                                                                                    
 330      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 331                                                                                                                    
 332      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 333                                                                                                                    
 334      // Related to the auto-advancing of widgets                                                                   
 335      private final int ADVANCE_MSG = 1;                                                                            
 336      private final int mAdvanceInterval = 20000;                                                                   
 337      private final int mAdvanceStagger = 250;                                                                      
 338      private long mAutoAdvanceSentTime;                                                                            
 339      private long mAutoAdvanceTimeLeft = -1;                                                                       
 340      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 341          new HashMap<View, AppWidgetProviderInfo>();                                                               
 342                                                                                                                    
 343      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 344      // match the sensor state.                                                                                    
 345      private final int mRestoreScreenOrientationDelay = 500;                                                       
 346                                                                                                                    
 347      // External icons saved in case of resource changes, orientation, etc.                                        
 348      private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];                    
 349      private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];                     
 350 -    private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2];                       
 351 -                                                                                                                  
 352 -    private Intent mAppMarketIntent = null;                                                                       
 353 -    private static final boolean DISABLE_MARKET_BUTTON = true;                                                    
 354                                                                                                                    
 355      private Drawable mWorkspaceBackgroundDrawable;                                                                
 356                                                                                                                    
 357      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 358      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 359                                                                                                                    
 360      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 361      static Date sDateStamp = new Date();                                                                          
 362      static DateFormat sDateFormat =                                                                               
 363              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 364      static long sRunStart = System.currentTimeMillis();                                                           
 365      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 366                                                                                                                    
 367      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 368      // it from the context.                                                                                       
 369      private SharedPreferences mSharedPrefs;                                                                       
 370                                                                                                                    
 371      private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 372                                                                                                                    
 373      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 374      // when we scroll to that page on resume.                                                                     
 375      private ImageView mFolderIconImageView;                                                                       
 376      private Bitmap mFolderIconBitmap;                                                                             
 377      private Canvas mFolderIconCanvas;                                                                             
 378      private Rect mRectForFolderAnimation = new Rect();                                                            
 379                                                                                                                    
 380      private BubbleTextView mWaitingForResume;                                                                     
 381                                                                                                                    
 382      private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 383          public void run() {                                                                                       
 384              if (mWorkspace != null) {                                                                             
 385                  mWorkspace.buildPageHardwareLayers();                                                             
 386              }                                                                                                     
 387          }                                                                                                         
 388      };                                                                                                            
 389                                                                                                                    
 390 -    private static ArrayList<PendingAddArguments> sPendingAddList                                                 
 391 -            = new ArrayList<PendingAddArguments>();                                                               
 392 +    private static PendingAddArguments sPendingAddItem;                                                           
 393                                                                                                                    
 394      public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);               
 395                                                                                                                    
 396      private static class PendingAddArguments {                                                                    
 397          int requestCode;                                                                                          
 398          Intent intent;                                                                                            
 399          long container;                                                                                           
 400          long screenId;                                                                                            
 401          int cellX;                                                                                                
 402          int cellY;                                                                                                
 403 +        int appWidgetId;                                                                                          
 404      }                                                                                                             
 405                                                                                                                    
 406      private Stats mStats;                                                                                         
 407 +                                                                                                                  
 408 +    FocusIndicatorView mFocusHandler;                                                                             
 409                                                                                                                    
 410      static boolean isPropertyEnabled(String propertyName) {                                                       
 411          return Log.isLoggable(propertyName, Log.VERBOSE);                                                         
 412      }                                                                                                             
 413                                                                                                                    
 414      @Override                                                                                                     
 415      protected void onCreate(Bundle savedInstanceState) {                                                          
 416          if (DEBUG_STRICT_MODE) {                                                                                  
 417              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 418                      .detectDiskReads()                                                                            
 419                      .detectDiskWrites()                                                                           
 420                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 421                      .penaltyLog()                                                                                 
 422                      .build());                                                                                    
 423              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 424                      .detectLeakedSqlLiteObjects()                                                                 
 425                      .detectLeakedClosableObjects()                                                                
 426                      .penaltyLog()                                                                                 
 427                      .penaltyDeath()                                                                               
 428                      .build());                                                                                    
 429          }                                                                                                         
 430                                                                                                                    
 431          super.onCreate(savedInstanceState);                                                                       
 432                                                                                                                    
 433          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 434          LauncherAppState app = LauncherAppState.getInstance();                                                    
 435 -                                                                                                                  
 436 +        LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 437          // Determine the dynamic grid properties                                                                  
 438          Point smallestSize = new Point();                                                                         
 439          Point largestSize = new Point();                                                                          
 440          Point realSize = new Point();                                                                             
 441          Display display = getWindowManager().getDefaultDisplay();                                                 
 442          display.getCurrentSizeRange(smallestSize, largestSize);                                                   
 443          display.getRealSize(realSize);                                                                            
 444          DisplayMetrics dm = new DisplayMetrics();                                                                 
 445          display.getMetrics(dm);                                                                                   
 446                                                                                                                    
 447          // Lazy-initialize the dynamic grid                                                                       
 448          DeviceProfile grid = app.initDynamicGrid(this,                                                            
 449                  Math.min(smallestSize.x, smallestSize.y),                                                         
 450                  Math.min(largestSize.x, largestSize.y),                                                           
 451                  realSize.x, realSize.y,                                                                           
 452                  dm.widthPixels, dm.heightPixels);                                                                 
 453                                                                                                                    
 454          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 455          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 456                  Context.MODE_PRIVATE);                                                                            
 457 +        mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 458          mModel = app.setLauncher(this);                                                                           
 459          mIconCache = app.getIconCache();                                                                          
 460          mIconCache.flushInvalidIcons(grid);                                                                       
 461          mDragController = new DragController(this);                                                               
 462 -        mLauncherClings = new LauncherClings(this);                                                               
 463          mInflater = getLayoutInflater();                                                                          
 464                                                                                                                    
 465          mStats = new Stats(this);                                                                                 
 466                                                                                                                    
 467 -        mAppWidgetManager = AppWidgetManager.getInstance(this);                                                   
 468 +        mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 469                                                                                                                    
 470          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 471          mAppWidgetHost.startListening();                                                                          
 472                                                                                                                    
 473          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 474          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 475          // LauncherModel load.                                                                                    
 476          mPaused = false;                                                                                          
 477                                                                                                                    
 478          if (PROFILE_STARTUP) {                                                                                    
 479              android.os.Debug.startMethodTracing(                                                                  
 480                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 481          }                                                                                                         
 482                                                                                                                    
 483 -                                                                                                                  
 484          checkForLocaleChange();                                                                                   
 485          setContentView(R.layout.launcher);                                                                        
 486                                                                                                                    
 487          setupViews();                                                                                             
 488          grid.layout(this);                                                                                        
 489                                                                                                                    
 490          registerContentObservers();                                                                               
 491                                                                                                                    
 492          lockAllApps();                                                                                            
 493                                                                                                                    
 494          mSavedState = savedInstanceState;                                                                         
 495          restoreState(mSavedState);                                                                                
 496                                                                                                                    
 497          if (PROFILE_STARTUP) {                                                                                    
 498              android.os.Debug.stopMethodTracing();                                                                 
 499          }                                                                                                         
 500                                                                                                                    
 501          if (!mRestoring) {                                                                                        
 502 -            if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE || sPausedFromUserAction) {                              
 503 +            if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 504                  // If the user leaves launcher, then we should just load items asynchronously when                
 505                  // they return.                                                                                   
 506                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 507              } else {                                                                                              
 508                  // We only load the page synchronously if the user rotates (or triggers a                         
 509                  // configuration change) while launcher is in the foreground                                      
 510                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 511              }                                                                                                     
 512          }                                                                                                         
 513                                                                                                                    
 514          // For handling default keys                                                                              
 515          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 516          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 517                                                                                                                    
 518          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 519          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 520                                                                                                                    
 521          updateGlobalIcons();                                                                                      
 522                                                                                                                    
 523          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 524          unlockScreenOrientation(true);                                                                            
 525                                                                                                                    
 526 -        // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
 527 -        // on the device, then we always show the first run cling experience (or if there is no                   
 528 -        // launcher2). Otherwise, we prompt the user upon started for migration                                   
 529 -        showFirstRunActivity();                                                                                   
 530 -        if (mLauncherClings.shouldShowFirstRunOrMigrationClings()) {                                              
 531 -            if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
 532 -                mLauncherClings.showMigrationCling();                                                             
 533 -            } else {                                                                                              
 534 -                mLauncherClings.showFirstRunCling();                                                              
 535 -            }                                                                                                     
 536 +        if (shouldShowIntroScreen()) {                                                                            
 537 +            showIntroScreen();                                                                                    
 538          } else {                                                                                                  
 539 -            mLauncherClings.removeFirstRunAndMigrationClings();                                                   
 540 -        }                                                                                                         
 541 -    }                                                                                                             
 542 -                                                                                                                  
 543 -    protected void onUserLeaveHint() {                                                                            
 544 -        super.onUserLeaveHint();                                                                                  
 545 -        sPausedFromUserAction = true;                                                                             
 546 -    }                                                                                                             
 547 +            showFirstRunActivity();                                                                               
 548 +            showFirstRunClings();                                                                                 
 549 +        }                                                                                                         
 550 +    }                                                                                                             
 551 +                                                                                                                  
 552 +    @Override                                                                                                     
 553 +    public void onLauncherProviderChange() { }                                                                    
 554                                                                                                                    
 555      /** To be overriden by subclasses to hint to Launcher that we have custom content */                          
 556      protected boolean hasCustomContentToLeft() {                                                                  
 557          return false;                                                                                             
 558      }                                                                                                             
 559                                                                                                                    
 560      /**                                                                                                           
 561       * To be overridden by subclasses to populate the custom content container and call                           
 562       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 563       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 564       */                                                                                                           
 565      protected void populateCustomContentContainer() {                                                             
 566 -    }                                                                                                             
 567 -                                                                                                                  
 568 -    /**                                                                                                           
 569 -     * To be overridden by subclasses to indicate that there is an activity to launch                             
 570 -     * before showing the standard launcher experience.                                                           
 571 -     */                                                                                                           
 572 -    protected boolean hasFirstRunActivity() {                                                                     
 573 -        return false;                                                                                             
 574 -    }                                                                                                             
 575 -                                                                                                                  
 576 -    /**                                                                                                           
 577 -     * To be overridden by subclasses to launch any first run activity                                            
 578 -     */                                                                                                           
 579 -    protected Intent getFirstRunActivity() {                                                                      
 580 -        return null;                                                                                              
 581      }                                                                                                             
 582                                                                                                                    
 583      /**                                                                                                           
 584       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 585       * ensure the custom content page is added or removed if necessary.                                           
 586       */                                                                                                           
 587      protected void invalidateHasCustomContentToLeft() {                                                           
 588          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 589              // Not bound yet, wait for bindScreens to be called.                                                  
 590              return;                                                                                               
 591          }                                                                                                         
 592                                                                                                                    
 593          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 594              // Create the custom content page and call the subclass to populate it.                               
 595              mWorkspace.createCustomContentContainer();                                                            
 596              populateCustomContentContainer();                                                                     
 597          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 598              mWorkspace.removeCustomContentPage();                                                                 
 599          }                                                                                                         
 600      }                                                                                                             
 601                                                                                                                    
 602      private void updateGlobalIcons() {                                                                            
 603          boolean searchVisible = false;                                                                            
 604          boolean voiceVisible = false;                                                                             
 605          // If we have a saved version of these external icons, we load them up immediately                        
 606          int coi = getCurrentOrientationIndexForGlobalIcons();                                                     
 607 -        if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null ||                                    
 608 -                sAppMarketIcon[coi] == null) {                                                                    
 609 -            if (!DISABLE_MARKET_BUTTON) {                                                                         
 610 -                updateAppMarketIcon();                                                                            
 611 -            }                                                                                                     
 612 +        if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {                                    
 613              searchVisible = updateGlobalSearchIcon();                                                             
 614              voiceVisible = updateVoiceSearchIcon(searchVisible);                                                  
 615          }                                                                                                         
 616          if (sGlobalSearchIcon[coi] != null) {                                                                     
 617               updateGlobalSearchIcon(sGlobalSearchIcon[coi]);                                                      
 618               searchVisible = true;                                                                                
 619          }                                                                                                         
 620          if (sVoiceSearchIcon[coi] != null) {                                                                      
 621              updateVoiceSearchIcon(sVoiceSearchIcon[coi]);                                                         
 622              voiceVisible = true;                                                                                  
 623 -        }                                                                                                         
 624 -        if (!DISABLE_MARKET_BUTTON && sAppMarketIcon[coi] != null) {                                              
 625 -            updateAppMarketIcon(sAppMarketIcon[coi]);                                                             
 626          }                                                                                                         
 627          if (mSearchDropTargetBar != null) {                                                                       
 628              mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                            
 629          }                                                                                                         
 630      }                                                                                                             
 631                                                                                                                    
 632      private void checkForLocaleChange() {                                                                         
 633          if (sLocaleConfiguration == null) {                                                                       
 634              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 635                  @Override                                                                                         
 636                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 637                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 638                      readConfiguration(Launcher.this, localeConfiguration);                                        
 639                      return localeConfiguration;                                                                   
 640                  }                                                                                                 
 641                                                                                                                    
 642                  @Override                                                                                         
 643                  protected void onPostExecute(LocaleConfiguration result) {                                        
 644                      sLocaleConfiguration = result;                                                                
 645                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 646                  }                                                                                                 
 647              }.execute();                                                                                          
 648              return;                                                                                               
 649          }                                                                                                         
 650                                                                                                                    
 651          final Configuration configuration = getResources().getConfiguration();                                    
 652                                                                                                                    
 653          final String previousLocale = sLocaleConfiguration.locale;                                                
 654          final String locale = configuration.locale.toString();                                                    
 655                                                                                                                    
 656          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 657          final int mcc = configuration.mcc;                                                                        
 658                                                                                                                    
 659          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 660          final int mnc = configuration.mnc;                                                                        
 661                                                                                                                    
 662          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 663                                                                                                                    
 664          if (localeChanged) {                                                                                      
 665              sLocaleConfiguration.locale = locale;                                                                 
 666              sLocaleConfiguration.mcc = mcc;                                                                       
 667              sLocaleConfiguration.mnc = mnc;                                                                       
 668                                                                                                                    
 669              mIconCache.flush();                                                                                   
 670                                                                                                                    
 671              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 672              new AsyncTask<Void, Void, Void>() {                                                                   
 673                  public Void doInBackground(Void ... args) {                                                       
 674                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 675                      return null;                                                                                  
 676                  }                                                                                                 
 677              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 678          }                                                                                                         
 679      }                                                                                                             
 680                                                                                                                    
 681      private static class LocaleConfiguration {                                                                    
 682          public String locale;                                                                                     
 683          public int mcc = -1;                                                                                      
 684          public int mnc = -1;                                                                                      
 685      }                                                                                                             
 686                                                                                                                    
 687      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 688          DataInputStream in = null;                                                                                
 689          try {                                                                                                     
 690              in = new DataInputStream(context.openFileInput(PREFERENCES));                                         
 691              configuration.locale = in.readUTF();                                                                  
 692              configuration.mcc = in.readInt();                                                                     
 693              configuration.mnc = in.readInt();                                                                     
 694          } catch (FileNotFoundException e) {                                                                       
 695              // Ignore                                                                                             
 696          } catch (IOException e) {                                                                                 
 697              // Ignore                                                                                             
 698          } finally {                                                                                               
 699              if (in != null) {                                                                                     
 700                  try {                                                                                             
 701                      in.close();                                                                                   
 702                  } catch (IOException e) {                                                                         
 703                      // Ignore                                                                                     
 704                  }                                                                                                 
 705              }                                                                                                     
 706          }                                                                                                         
 707      }                                                                                                             
 708                                                                                                                    
 709      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 710          DataOutputStream out = null;                                                                              
 711          try {                                                                                                     
 712              out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));                        
 713              out.writeUTF(configuration.locale);                                                                   
 714              out.writeInt(configuration.mcc);                                                                      
 715              out.writeInt(configuration.mnc);                                                                      
 716              out.flush();                                                                                          
 717          } catch (FileNotFoundException e) {                                                                       
 718              // Ignore                                                                                             
 719          } catch (IOException e) {                                                                                 
 720              //noinspection ResultOfMethodCallIgnored                                                              
 721              context.getFileStreamPath(PREFERENCES).delete();                                                      
 722          } finally {                                                                                               
 723              if (out != null) {                                                                                    
 724                  try {                                                                                             
 725                      out.close();                                                                                  
 726                  } catch (IOException e) {                                                                         
 727                      // Ignore                                                                                     
 728                  }                                                                                                 
 729              }                                                                                                     
 730          }                                                                                                         
 731      }                                                                                                             
 732                                                                                                                    
 733      public Stats getStats() {                                                                                     
 734          return mStats;                                                                                            
 735      }                                                                                                             
 736                                                                                                                    
 737      public LayoutInflater getInflater() {                                                                         
 738          return mInflater;                                                                                         
 739      }                                                                                                             
 740                                                                                                                    
 741      boolean isDraggingEnabled() {                                                                                 
 742          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 743          // that is subsequently removed from the workspace in startBinding().                                     
 744          return !mModel.isLoadingWorkspace();                                                                      
 745      }                                                                                                             
 746                                                                                                                    
 747      static int getScreen() {                                                                                      
 748          synchronized (sLock) {                                                                                    
 749              return sScreen;                                                                                       
 750          }                                                                                                         
 751      }                                                                                                             
 752                                                                                                                    
 753      static void setScreen(int screen) {                                                                           
 754          synchronized (sLock) {                                                                                    
 755              sScreen = screen;                                                                                     
 756          }                                                                                                         
 757      }                                                                                                             
 758                                                                                                                    
 759 -    /**                                                                                                           
 760 -     * Copied from View -- the View version of the method isn't called                                            
 761 -     * anywhere else in our process and only exists for API level 17+,                                            
 762 -     * so it's ok to keep our own version with no API requirement.                                                
 763 -     */                                                                                                           
 764      public static int generateViewId() {                                                                          
 765 -        for (;;) {                                                                                                
 766 -            final int result = sNextGeneratedId.get();                                                            
 767 -            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                      
 768 -            int newValue = result + 1;                                                                            
 769 -            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                    
 770 -            if (sNextGeneratedId.compareAndSet(result, newValue)) {                                               
 771 -                return result;                                                                                    
 772 +        if (Build.VERSION.SDK_INT >= 17) {                                                                        
 773 +            return View.generateViewId();                                                                         
 774 +        } else {                                                                                                  
 775 +            // View.generateViewId() is not available. The following fallback logic is a copy                     
 776 +            // of its implementation.                                                                             
 777 +            for (;;) {                                                                                            
 778 +                final int result = sNextGeneratedId.get();                                                        
 779 +                // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 780 +                int newValue = result + 1;                                                                        
 781 +                if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 782 +                if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 783 +                    return result;                                                                                
 784 +                }                                                                                                 
 785              }                                                                                                     
 786          }                                                                                                         
 787      }                                                                                                             
 788                                                                                                                    
 789      public int getViewIdForItem(ItemInfo info) {                                                                  
 790          // This cast is safe given the > 2B range for int.                                                        
 791          int itemId = (int) info.id;                                                                               
 792          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 793              return mItemIdToViewId.get(itemId);                                                                   
 794          }                                                                                                         
 795          int viewId = generateViewId();                                                                            
 796          mItemIdToViewId.put(itemId, viewId);                                                                      
 797          return viewId;                                                                                            
 798      }                                                                                                             
 799                                                                                                                    
 800      /**                                                                                                           
 801       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 802       * a configuration step, this allows the proper animations to run after other transitions.                    
 803       */                                                                                                           
 804 -    private boolean completeAdd(PendingAddArguments args) {                                                       
 805 -        boolean result = false;                                                                                   
 806 +    private long completeAdd(PendingAddArguments args) {                                                          
 807 +        long screenId = args.screenId;                                                                            
 808 +        if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 809 +            // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 810 +            // that the drop page actually exists.                                                                
 811 +            screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 812 +        }                                                                                                         
 813 +                                                                                                                  
 814          switch (args.requestCode) {                                                                               
 815 -            case REQUEST_PICK_APPLICATION:                                                                        
 816 -                completeAddApplication(args.intent, args.container, args.screenId, args.cellX,                    
 817 +            case REQUEST_CREATE_SHORTCUT:                                                                         
 818 +                completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 819                          args.cellY);                                                                              
 820                  break;                                                                                            
 821 -            case REQUEST_PICK_SHORTCUT:                                                                           
 822 -                processShortcut(args.intent);                                                                     
 823 +            case REQUEST_CREATE_APPWIDGET:                                                                        
 824 +                completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 825                  break;                                                                                            
 826 -            case REQUEST_CREATE_SHORTCUT:                                                                         
 827 -                completeAddShortcut(args.intent, args.container, args.screenId, args.cellX,                       
 828 -                        args.cellY);                                                                              
 829 -                result = true;                                                                                    
 830 -                break;                                                                                            
 831 -            case REQUEST_CREATE_APPWIDGET:                                                                        
 832 -                int appWidgetId = args.intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);               
 833 -                completeAddAppWidget(appWidgetId, args.container, args.screenId, null, null);                     
 834 -                result = true;                                                                                    
 835 +            case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 836 +                completeRestoreAppWidget(args.appWidgetId);                                                       
 837                  break;                                                                                            
 838          }                                                                                                         
 839          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 840          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 841          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 842          resetAddInfo();                                                                                           
 843 -        return result;                                                                                            
 844 +        return screenId;                                                                                          
 845      }                                                                                                             
 846                                                                                                                    
 847      @Override                                                                                                     
 848      protected void onActivityResult(                                                                              
 849              final int requestCode, final int resultCode, final Intent data) {                                     
 850          // Reset the startActivity waiting flag                                                                   
 851 -        mWaitingForResult = false;                                                                                
 852 -        int pendingAddWidgetId = mPendingAddWidgetId;                                                             
 853 +        setWaitingForResult(false);                                                                               
 854 +        final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 855          mPendingAddWidgetId = -1;                                                                                 
 856                                                                                                                    
 857          Runnable exitSpringLoaded = new Runnable() {                                                              
 858              @Override                                                                                             
 859              public void run() {                                                                                   
 860                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 861                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 862              }                                                                                                     
 863          };                                                                                                        
 864                                                                                                                    
 865          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 866              final int appWidgetId = data != null ?                                                                
 867                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 868              if (resultCode == RESULT_CANCELED) {                                                                  
 869                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 870 -                mWorkspace.removeExtraEmptyScreen(true, exitSpringLoaded,                                         
 871 +                mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 872                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 873              } else if (resultCode == RESULT_OK) {                                                                 
 874                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 875                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 876              }                                                                                                     
 877              return;                                                                                               
 878          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 879              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 880                  mWorkspace.exitOverviewMode(false);                                                               
 881              }                                                                                                     
 882              return;                                                                                               
 883          }                                                                                                         
 884                                                                                                                    
 885          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 886                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 887                                                                                                                    
 888 +        final boolean workspaceLocked = isWorkspaceLocked();                                                      
 889          // We have special handling for widgets                                                                   
 890          if (isWidgetDrop) {                                                                                       
 891              final int appWidgetId;                                                                                
 892              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 893                      : -1;                                                                                         
 894              if (widgetId < 0) {                                                                                   
 895                  appWidgetId = pendingAddWidgetId;                                                                 
 896              } else {                                                                                              
 897                  appWidgetId = widgetId;                                                                           
 898              }                                                                                                     
 899                                                                                                                    
 900              final int result;                                                                                     
 901 -            final Runnable onComplete;                                                                            
 902              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 903 -                Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not returned from the \\" +               
 904 -                        "widget configuration activity.");                                                        
 905 +                Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 906 +                        "returned from the widget configuration activity.");                                      
 907                  result = RESULT_CANCELED;                                                                         
 908                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 909 -                onComplete = new Runnable() {                                                                     
 910 +                final Runnable onComplete = new Runnable() {                                                      
 911                      @Override                                                                                     
 912                      public void run() {                                                                           
 913                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 914                      }                                                                                             
 915                  };                                                                                                
 916 +                if (workspaceLocked) {                                                                            
 917 +                    // No need to remove the empty screen if we're mid-binding, as the                            
 918 +                    // the bind will not add the empty screen.                                                    
 919 +                    mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 920 +                } else {                                                                                          
 921 +                    mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 922 +                            ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 923 +                }                                                                                                 
 924              } else {                                                                                              
 925 -                result = resultCode;                                                                              
 926 -                final CellLayout dropLayout =                                                                     
 927 -                        (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                        
 928 -                dropLayout.setDropPending(true);                                                                  
 929 -                onComplete = new Runnable() {                                                                     
 930 -                    @Override                                                                                     
 931 -                    public void run() {                                                                           
 932 -                        completeTwoStageWidgetDrop(result, appWidgetId);                                          
 933 -                        dropLayout.setDropPending(false);                                                         
 934 +                if (!workspaceLocked) {                                                                           
 935 +                    if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 936 +                        // When the screen id represents an actual screen (as opposed to a rank)                  
 937 +                        // we make sure that the drop page actually exists.                                       
 938 +                        mPendingAddInfo.screenId =                                                                
 939 +                                ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 940                      }                                                                                             
 941 -                };                                                                                                
 942 -            }                                                                                                     
 943 -            mWorkspace.removeExtraEmptyScreen(true, onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY,               
 944 -                    false);                                                                                       
 945 +                    final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 946 +                                                                                                                  
 947 +                    dropLayout.setDropPending(true);                                                              
 948 +                    final Runnable onComplete = new Runnable() {                                                  
 949 +                        @Override                                                                                 
 950 +                        public void run() {                                                                       
 951 +                            completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 952 +                            dropLayout.setDropPending(false);                                                     
 953 +                        }                                                                                         
 954 +                    };                                                                                            
 955 +                    mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 956 +                            ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 957 +                } else {                                                                                          
 958 +                    PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 959 +                            mPendingAddInfo);                                                                     
 960 +                    sPendingAddItem = args;                                                                       
 961 +                }                                                                                                 
 962 +            }                                                                                                     
 963 +            return;                                                                                               
 964 +        }                                                                                                         
 965 +                                                                                                                  
 966 +        if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 967 +            if (resultCode == RESULT_OK) {                                                                        
 968 +                // Update the widget view.                                                                        
 969 +                PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 970 +                        pendingAddWidgetId, mPendingAddInfo);                                                     
 971 +                if (workspaceLocked) {                                                                            
 972 +                    sPendingAddItem = args;                                                                       
 973 +                } else {                                                                                          
 974 +                    completeAdd(args);                                                                            
 975 +                }                                                                                                 
 976 +            }                                                                                                     
 977 +            // Leave the widget in the pending state if the user canceled the configure.                          
 978              return;                                                                                               
 979          }                                                                                                         
 980                                                                                                                    
 981          // The pattern used here is that a user PICKs a specific application,                                     
 982          // which, depending on the target, might need to CREATE the actual target.                                
 983                                                                                                                    
 984          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 985          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 986          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 987 -            final PendingAddArguments args = new PendingAddArguments();                                           
 988 -            args.requestCode = requestCode;                                                                       
 989 -            args.intent = data;                                                                                   
 990 -            args.container = mPendingAddInfo.container;                                                           
 991 -            args.screenId = mPendingAddInfo.screenId;                                                             
 992 -            args.cellX = mPendingAddInfo.cellX;                                                                   
 993 -            args.cellY = mPendingAddInfo.cellY;                                                                   
 994 +            final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 995 +                    mPendingAddInfo);                                                                             
 996              if (isWorkspaceLocked()) {                                                                            
 997 -                sPendingAddList.add(args);                                                                        
 998 +                sPendingAddItem = args;                                                                           
 999              } else {                                                                                              
1000                  completeAdd(args);                                                                                
1001 -            }                                                                                                     
1002 -            mWorkspace.removeExtraEmptyScreen(true, exitSpringLoaded,                                             
1003 +                mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
1004 +                        ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
1005 +            }                                                                                                     
1006 +        } else if (resultCode == RESULT_CANCELED) {                                                               
1007 +            mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
1008                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
1009 -        } else if (resultCode == RESULT_CANCELED) {                                                               
1010 -            mWorkspace.removeExtraEmptyScreen(true, exitSpringLoaded,                                             
1011 -                    ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
1012          }                                                                                                         
1013          mDragLayer.clearAnimatedView();                                                                           
1014 +    }                                                                                                             
1015 +                                                                                                                  
1016 +    private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
1017 +            appWidgetId, ItemInfo info) {                                                                         
1018 +        PendingAddArguments args = new PendingAddArguments();                                                     
1019 +        args.requestCode = requestCode;                                                                           
1020 +        args.intent = data;                                                                                       
1021 +        args.container = info.container;                                                                          
1022 +        args.screenId = info.screenId;                                                                            
1023 +        args.cellX = info.cellX;                                                                                  
1024 +        args.cellY = info.cellY;                                                                                  
1025 +        args.appWidgetId = appWidgetId;                                                                           
1026 +        return args;                                                                                              
1027 +    }                                                                                                             
1028 +                                                                                                                  
1029 +    /**                                                                                                           
1030 +     * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
1031 +     *                                                                                                            
1032 +     * @param screenId the screen id to check                                                                     
1033 +     * @return the new screen, or screenId if it exists                                                           
1034 +     */                                                                                                           
1035 +    private long ensurePendingDropLayoutExists(long screenId) {                                                   
1036 +        CellLayout dropLayout =                                                                                   
1037 +                (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
1038 +        if (dropLayout == null) {                                                                                 
1039 +            // it's possible that the add screen was removed because it was                                       
1040 +            // empty and a re-bind occurred                                                                       
1041 +            mWorkspace.addExtraEmptyScreen();                                                                     
1042 +            return mWorkspace.commitExtraEmptyScreen();                                                           
1043 +        } else {                                                                                                  
1044 +            return screenId;                                                                                      
1045 +        }                                                                                                         
1046      }                                                                                                             
1047                                                                                                                    
1048      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
1049          CellLayout cellLayout =                                                                                   
1050                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
1051          Runnable onCompleteRunnable = null;                                                                       
1052          int animationType = 0;                                                                                    
1053                                                                                                                    
1054          AppWidgetHostView boundWidget = null;                                                                     
1055          if (resultCode == RESULT_OK) {                                                                            
1056              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
1057              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
1058                      mPendingAddWidgetInfo);                                                                       
1059              boundWidget = layout;                                                                                 
1060              onCompleteRunnable = new Runnable() {                                                                 
1061                  @Override                                                                                         
1062                  public void run() {                                                                               
1063                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
1064                              mPendingAddInfo.screenId, layout, null);                                              
1065                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
1066                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
1067                  }                                                                                                 
1068              };                                                                                                    
1069          } else if (resultCode == RESULT_CANCELED) {                                                               
1070              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
1071              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
1072          }                                                                                                         
1073          if (mDragLayer.getAnimatedView() != null) {                                                               
1074              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
1075                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
1076                      animationType, boundWidget, true);                                                            
1077          } else if (onCompleteRunnable != null) {                                                                  
1078              // The animated view may be null in the case of a rotation during widget configuration                
1079              onCompleteRunnable.run();                                                                             
1080          }                                                                                                         
1081      }                                                                                                             
1082                                                                                                                    
1083      @Override                                                                                                     
1084      protected void onStop() {                                                                                     
1085          super.onStop();                                                                                           
1086          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
1087      }                                                                                                             
1088                                                                                                                    
1089      @Override                                                                                                     
1090      protected void onStart() {                                                                                    
1091          super.onStart();                                                                                          
1092          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
1093      }                                                                                                             
1094                                                                                                                    
1095      @Override                                                                                                     
1096      protected void onResume() {                                                                                   
1097          long startTime = 0;                                                                                       
1098          if (DEBUG_RESUME_TIME) {                                                                                  
1099              startTime = System.currentTimeMillis();                                                               
1100              Log.v(TAG, "Launcher.onResume()");                                                                    
1101          }                                                                                                         
1102          super.onResume();                                                                                         
1103                                                                                                                    
1104          // Restore the previous launcher state                                                                    
1105          if (mOnResumeState == State.WORKSPACE) {                                                                  
1106              showWorkspace(false);                                                                                 
1107          } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
1108              showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    
1109          }                                                                                                         
1110          mOnResumeState = State.NONE;                                                                              
1111                                                                                                                    
1112          // Background was set to gradient in onPause(), restore to black if in all apps.                          
1113          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
1114                                                                                                                    
1115          mPaused = false;                                                                                          
1116 -        sPausedFromUserAction = false;                                                                            
1117          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
1118 -            mWorkspaceLoading = true;                                                                             
1119 +            setWorkspaceLoading(true);                                                                            
1120              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
1121              mRestoring = false;                                                                                   
1122              mOnResumeNeedsLoad = false;                                                                           
1123          }                                                                                                         
1124          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1125              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1126              // execute them here                                                                                  
1127              long startTimeCallbacks = 0;                                                                          
1128              if (DEBUG_RESUME_TIME) {                                                                              
1129                  startTimeCallbacks = System.currentTimeMillis();                                                  
1130              }                                                                                                     
1131                                                                                                                    
1132              if (mAppsCustomizeContent != null) {                                                                  
1133                  mAppsCustomizeContent.setBulkBind(true);                                                          
1134              }                                                                                                     
1135              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1136                  mBindOnResumeCallbacks.get(i).run();                                                              
1137              }                                                                                                     
1138              if (mAppsCustomizeContent != null) {                                                                  
1139                  mAppsCustomizeContent.setBulkBind(false);                                                         
1140              }                                                                                                     
1141              mBindOnResumeCallbacks.clear();                                                                       
1142              if (DEBUG_RESUME_TIME) {                                                                              
1143                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1144                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1145              }                                                                                                     
1146          }                                                                                                         
1147          if (mOnResumeCallbacks.size() > 0) {                                                                      
1148              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1149                  mOnResumeCallbacks.get(i).run();                                                                  
1150              }                                                                                                     
1151              mOnResumeCallbacks.clear();                                                                           
1152          }                                                                                                         
1153                                                                                                                    
1154          // Reset the pressed state of icons that were locked in the press state while activities                  
1155          // were launching                                                                                         
1156          if (mWaitingForResume != null) {                                                                          
1157              // Resets the previous workspace icon press state                                                     
1158              mWaitingForResume.setStayPressed(false);                                                              
1159          }                                                                                                         
1160 -        if (mAppsCustomizeContent != null) {                                                                      
1161 -            // Resets the previous all apps icon press state                                                      
1162 -            mAppsCustomizeContent.resetDrawableState();                                                           
1163 -        }                                                                                                         
1164                                                                                                                    
1165          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1166          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1167          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1168          // orientation.                                                                                           
1169          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1170                                                                                                                    
1171          // Process any items that were added while Launcher was away.                                             
1172          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1173                                                                                                                    
1174          // Update the voice search button proxy                                                                   
1175          updateVoiceButtonProxyVisible(false);                                                                     
1176                                                                                                                    
1177          // Again, as with the above scenario, it's possible that one or more of the global icons                  
1178          // were updated in the wrong orientation.                                                                 
1179          updateGlobalIcons();                                                                                      
1180          if (DEBUG_RESUME_TIME) {                                                                                  
1181              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1182          }                                                                                                         
1183                                                                                                                    
1184          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1185              // If we are resuming and the custom content is the current page, we call onShow().                   
1186              // It is also poassible that onShow will instead be called slightly after first layout                
1187              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1188              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1189 -                mWorkspace.getCustomContentCallbacks().onShow();                                                  
1190 +                mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1191              }                                                                                                     
1192          }                                                                                                         
1193          mWorkspace.updateInteractionForState();                                                                   
1194          mWorkspace.onResume();                                                                                    
1195 +                                                                                                                  
1196 +        PackageInstallerCompat.getInstance(this).onResume();                                                      
1197      }                                                                                                             
1198                                                                                                                    
1199      @Override                                                                                                     
1200      protected void onPause() {                                                                                    
1201          // Ensure that items added to Launcher are queued until Launcher returns                                  
1202          InstallShortcutReceiver.enableInstallQueue();                                                             
1203 +        PackageInstallerCompat.getInstance(this).onPause();                                                       
1204                                                                                                                    
1205          super.onPause();                                                                                          
1206          mPaused = true;                                                                                           
1207          mDragController.cancelDrag();                                                                             
1208          mDragController.resetLastGestureUpTime();                                                                 
1209                                                                                                                    
1210          // We call onHide() aggressively. The custom content callbacks should be able to                          
1211          // debounce excess onHide calls.                                                                          
1212          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1213              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1214          }                                                                                                         
1215      }                                                                                                             
1216                                                                                                                    
1217      QSBScroller mQsbScroller = new QSBScroller() {                                                                
1218          int scrollY = 0;                                                                                          
1219                                                                                                                    
1220          @Override                                                                                                 
1221          public void setScrollY(int scroll) {                                                                      
1222              scrollY = scroll;                                                                                     
1223                                                                                                                    
1224              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1225                  mSearchDropTargetBar.setTranslationY(- scrollY);                                                  
1226                  getQsbBar().setTranslationY(-scrollY);                                                            
1227              }                                                                                                     
1228          }                                                                                                         
1229      };                                                                                                            
1230                                                                                                                    
1231      public void resetQSBScroll() {                                                                                
1232          mSearchDropTargetBar.animate().translationY(0).start();                                                   
1233          getQsbBar().animate().translationY(0).start();                                                            
1234      }                                                                                                             
1235                                                                                                                    
1236      public interface CustomContentCallbacks {                                                                     
1237 -        // Custom content is completely shown                                                                     
1238 -        public void onShow();                                                                                     
1239 +        // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1240 +        // by a onResume or by scrolling otherwise.                                                               
1241 +        public void onShow(boolean fromResume);                                                                   
1242                                                                                                                    
1243          // Custom content is completely hidden                                                                    
1244          public void onHide();                                                                                     
1245                                                                                                                    
1246          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1247          public void onScrollProgressChanged(float progress);                                                      
1248 +                                                                                                                  
1249 +        // Indicates whether the user is allowed to scroll away from the custom content.                          
1250 +        boolean isScrollingAllowed();                                                                             
1251      }                                                                                                             
1252                                                                                                                    
1253      protected boolean hasSettings() {                                                                             
1254          return false;                                                                                             
1255 -    }                                                                                                             
1256 -                                                                                                                  
1257 -    protected void startSettings() {                                                                              
1258      }                                                                                                             
1259                                                                                                                    
1260      public interface QSBScroller {                                                                                
1261          public void setScrollY(int scrollY);                                                                      
1262      }                                                                                                             
1263                                                                                                                    
1264      public QSBScroller addToCustomContentPage(View customContent,                                                 
1265              CustomContentCallbacks callbacks, String description) {                                               
1266          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1267          return mQsbScroller;                                                                                      
1268      }                                                                                                             
1269                                                                                                                    
1270      // The custom content needs to offset its content to account for the QSB                                      
1271      public int getTopOffsetForCustomContent() {                                                                   
1272          return mWorkspace.getPaddingTop();                                                                        
1273      }                                                                                                             
1274                                                                                                                    
1275      @Override                                                                                                     
1276      public Object onRetainNonConfigurationInstance() {                                                            
1277          // Flag the loader to stop early before switching                                                         
1278 -        mModel.stopLoader();                                                                                      
1279 +        if (mModel.isCurrentCallbacks(this)) {                                                                    
1280 +            mModel.stopLoader();                                                                                  
1281 +        }                                                                                                         
1282          if (mAppsCustomizeContent != null) {                                                                      
1283              mAppsCustomizeContent.surrender();                                                                    
1284          }                                                                                                         
1285          return Boolean.TRUE;                                                                                      
1286      }                                                                                                             
1287                                                                                                                    
1288      // We can't hide the IME if it was forced open.  So don't bother                                              
1289      @Override                                                                                                     
1290      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1291          super.onWindowFocusChanged(hasFocus);                                                                     
1292          mHasFocus = hasFocus;                                                                                     
1293      }                                                                                                             
1294                                                                                                                    
1295      private boolean acceptFilter() {                                                                              
1296          final InputMethodManager inputManager = (InputMethodManager)                                              
1297                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1298          return !inputManager.isFullscreenMode();                                                                  
1299      }                                                                                                             
1300                                                                                                                    
1301      @Override                                                                                                     
1302      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1303          final int uniChar = event.getUnicodeChar();                                                               
1304          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1305          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1306          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1307              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1308                      keyCode, event);                                                                              
1309              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1310                  // something usable has been typed - start a search                                               
1311                  // the typed text will be retrieved and cleared by                                                
1312                  // showSearchDialog()                                                                             
1313                  // If there are multiple keystrokes before the search dialog takes focus,                         
1314                  // onSearchRequested() will be called for every keystroke,                                        
1315                  // but it is idempotent, so it's fine.                                                            
1316                  return onSearchRequested();                                                                       
1317              }                                                                                                     
1318          }                                                                                                         
1319                                                                                                                    
1320          // Eat the long press event so the keyboard doesn't come up.                                              
1321          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1322              return true;                                                                                          
1323          }                                                                                                         
1324                                                                                                                    
1325          return handled;                                                                                           
1326      }                                                                                                             
1327                                                                                                                    
1328      private String getTypedText() {                                                                               
1329          return mDefaultKeySsb.toString();                                                                         
1330      }                                                                                                             
1331                                                                                                                    
1332      private void clearTypedText() {                                                                               
1333          mDefaultKeySsb.clear();                                                                                   
1334          mDefaultKeySsb.clearSpans();                                                                              
1335          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1336      }                                                                                                             
1337                                                                                                                    
1338      /**                                                                                                           
1339       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1340       * State                                                                                                      
1341       */                                                                                                           
1342      private static State intToState(int stateOrdinal) {                                                           
1343          State state = State.WORKSPACE;                                                                            
1344          final State[] stateValues = State.values();                                                               
1345          for (int i = 0; i < stateValues.length; i++) {                                                            
1346              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1347                  state = stateValues[i];                                                                           
1348                  break;                                                                                            
1349              }                                                                                                     
1350          }                                                                                                         
1351          return state;                                                                                             
1352      }                                                                                                             
1353                                                                                                                    
1354      /**                                                                                                           
1355       * Restores the previous state, if it exists.                                                                 
1356       *                                                                                                            
1357       * @param savedState The previous state.                                                                      
1358       */                                                                                                           
1359      @SuppressWarnings("unchecked")                                                                                
1360      private void restoreState(Bundle savedState) {                                                                
1361          if (savedState == null) {                                                                                 
1362              return;                                                                                               
1363          }                                                                                                         
1364                                                                                                                    
1365          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1366          if (state == State.APPS_CUSTOMIZE) {                                                                      
1367              mOnResumeState = State.APPS_CUSTOMIZE;                                                                
1368          }                                                                                                         
1369                                                                                                                    
1370          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1371                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1372          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1373              mWorkspace.setRestorePage(currentScreen);                                                             
1374          }                                                                                                         
1375                                                                                                                    
1376          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1377          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1378                                                                                                                    
1379          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1380              mPendingAddInfo.container = pendingAddContainer;                                                      
1381              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1382              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1383              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1384              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1385              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1386              mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);              
1387              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1388 -            mWaitingForResult = true;                                                                             
1389 +            setWaitingForResult(true);                                                                            
1390              mRestoring = true;                                                                                    
1391          }                                                                                                         
1392                                                                                                                    
1393          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1394          if (renameFolder) {                                                                                       
1395              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1396              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1397              mRestoring = true;                                                                                    
1398          }                                                                                                         
1399                                                                                                                    
1400          // Restore the AppsCustomize tab                                                                          
1401          if (mAppsCustomizeTabHost != null) {                                                                      
1402              String curTab = savedState.getString("apps_customize_currentTab");                                    
1403              if (curTab != null) {                                                                                 
1404                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1405                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1406                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1407                          mAppsCustomizeContent.getCurrentPage());                                                  
1408              }                                                                                                     
1409                                                                                                                    
1410              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1411              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1412          }                                                                                                         
1413          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1414                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1415      }                                                                                                             
1416                                                                                                                    
1417      /**                                                                                                           
1418       * Finds all the views we need and configure them properly.                                                   
1419       */                                                                                                           
1420      private void setupViews() {                                                                                   
1421          final DragController dragController = mDragController;                                                    
1422                                                                                                                    
1423          mLauncherView = findViewById(R.id.launcher);                                                              
1424 +        mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1425          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1426          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1427 +        mWorkspace.setPageSwitchListener(this);                                                                   
1428          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1429                                                                                                                    
1430          mLauncherView.setSystemUiVisibility(                                                                      
1431                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1432          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1433                                                                                                                    
1434          // Setup the drag layer                                                                                   
1435          mDragLayer.setup(this, dragController);                                                                   
1436                                                                                                                    
1437          // Setup the hotseat                                                                                      
1438          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1439          if (mHotseat != null) {                                                                                   
1440              mHotseat.setup(this);                                                                                 
1441              mHotseat.setOnLongClickListener(this);                                                                
1442          }                                                                                                         
1443                                                                                                                    
1444          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1445          View widgetButton = findViewById(R.id.widget_button);                                                     
1446          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1447              @Override                                                                                             
1448              public void onClick(View arg0) {                                                                      
1449                  if (!mWorkspace.isSwitchingState()) {                                                             
1450 -                    showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                          
1451 +                    onClickAddWidgetButton(arg0);                                                                 
1452                  }                                                                                                 
1453              }                                                                                                     
1454          });                                                                                                       
1455          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1456                                                                                                                    
1457          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1458          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1459              @Override                                                                                             
1460              public void onClick(View arg0) {                                                                      
1461                  if (!mWorkspace.isSwitchingState()) {                                                             
1462 -                    startWallpaper();                                                                             
1463 +                    onClickWallpaperPicker(arg0);                                                                 
1464                  }                                                                                                 
1465              }                                                                                                     
1466          });                                                                                                       
1467          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1468                                                                                                                    
1469          View settingsButton = findViewById(R.id.settings_button);                                                 
1470          if (hasSettings()) {                                                                                      
1471              settingsButton.setOnClickListener(new OnClickListener() {                                             
1472                  @Override                                                                                         
1473                  public void onClick(View arg0) {                                                                  
1474                      if (!mWorkspace.isSwitchingState()) {                                                         
1475 -                        startSettings();                                                                          
1476 +                        onClickSettingsButton(arg0);                                                              
1477                      }                                                                                             
1478 -                    }                                                                                             
1479 +                }                                                                                                 
1480              });                                                                                                   
1481              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1482          } else {                                                                                                  
1483              settingsButton.setVisibility(View.GONE);                                                              
1484              FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();              
1485              lp.gravity = Gravity.END | Gravity.TOP;                                                               
1486              widgetButton.requestLayout();                                                                         
1487          }                                                                                                         
1488                                                                                                                    
1489          mOverviewPanel.setAlpha(0f);                                                                              
1490                                                                                                                    
1491          // Setup the workspace                                                                                    
1492          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1493          mWorkspace.setOnLongClickListener(this);                                                                  
1494          mWorkspace.setup(dragController);                                                                         
1495          dragController.addDragListener(mWorkspace);                                                               
1496                                                                                                                    
1497          // Get the search/delete bar                                                                              
1498          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1499                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1500                                                                                                                    
1501          // Setup AppsCustomize                                                                                    
1502          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1503          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1504                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1505          mAppsCustomizeContent.setup(this, dragController);                                                        
1506                                                                                                                    
1507          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1508          dragController.setDragScoller(mWorkspace);                                                                
1509          dragController.setScrollView(mDragLayer);                                                                 
1510          dragController.setMoveTarget(mWorkspace);                                                                 
1511          dragController.addDropTarget(mWorkspace);                                                                 
1512          if (mSearchDropTargetBar != null) {                                                                       
1513              mSearchDropTargetBar.setup(this, dragController);                                                     
1514          }                                                                                                         
1515                                                                                                                    
1516          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1517              Log.v(TAG, "adding WeightWatcher");                                                                   
1518              mWeightWatcher = new WeightWatcher(this);                                                             
1519              mWeightWatcher.setAlpha(0.5f);                                                                        
1520              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1521                      new FrameLayout.LayoutParams(                                                                 
1522                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1523                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1524                              Gravity.BOTTOM)                                                                       
1525              );                                                                                                    
1526                                                                                                                    
1527              boolean show = shouldShowWeightWatcher();                                                             
1528              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1529          }                                                                                                         
1530      }                                                                                                             
1531                                                                                                                    
1532      /**                                                                                                           
1533 +     * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1534 +     */                                                                                                           
1535 +    public void setAllAppsButton(View allAppsButton) {                                                            
1536 +        mAllAppsButton = allAppsButton;                                                                           
1537 +    }                                                                                                             
1538 +                                                                                                                  
1539 +    public View getAllAppsButton() {                                                                              
1540 +        return mAllAppsButton;                                                                                    
1541 +    }                                                                                                             
1542 +                                                                                                                  
1543 +    /**                                                                                                           
1544       * Creates a view representing a shortcut.                                                                    
1545       *                                                                                                            
1546       * @param info The data structure describing the shortcut.                                                    
1547       *                                                                                                            
1548       * @return A View inflated from R.layout.application.                                                         
1549       */                                                                                                           
1550      View createShortcut(ShortcutInfo info) {                                                                      
1551          return createShortcut(R.layout.application,                                                               
1552                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1553      }                                                                                                             
1554                                                                                                                    
1555      /**                                                                                                           
1556       * Creates a view representing a shortcut inflated from the specified resource.                               
1557       *                                                                                                            
1558       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1559       * @param parent The group the shortcut belongs to.                                                           
1560       * @param info The data structure describing the shortcut.                                                    
1561       *                                                                                                            
1562       * @return A View inflated from layoutResId.                                                                  
1563       */                                                                                                           
1564      View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                                   
1565          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1566 -        favorite.applyFromShortcutInfo(info, mIconCache);                                                         
1567 +        favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1568          favorite.setOnClickListener(this);                                                                        
1569 +        favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1570          return favorite;                                                                                          
1571 -    }                                                                                                             
1572 -                                                                                                                  
1573 -    /**                                                                                                           
1574 -     * Add an application shortcut to the workspace.                                                              
1575 -     *                                                                                                            
1576 -     * @param data The intent describing the application.                                                         
1577 -     * @param cellInfo The position on screen where to create the shortcut.                                       
1578 -     */                                                                                                           
1579 -    void completeAddApplication(Intent data, long container, long screenId, int cellX, int cellY) {               
1580 -        final int[] cellXY = mTmpAddItemCellCoordinates;                                                          
1581 -        final CellLayout layout = getCellLayout(container, screenId);                                             
1582 -                                                                                                                  
1583 -        // First we check if we already know the exact location where we want to add this item.                   
1584 -        if (cellX >= 0 && cellY >= 0) {                                                                           
1585 -            cellXY[0] = cellX;                                                                                    
1586 -            cellXY[1] = cellY;                                                                                    
1587 -        } else if (!layout.findCellForSpan(cellXY, 1, 1)) {                                                       
1588 -            showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1589 -            return;                                                                                               
1590 -        }                                                                                                         
1591 -                                                                                                                  
1592 -        final ShortcutInfo info = mModel.getShortcutInfo(getPackageManager(), data, this);                        
1593 -                                                                                                                  
1594 -        if (info != null) {                                                                                       
1595 -            info.setActivity(this, data.getComponent(), Intent.FLAG_ACTIVITY_NEW_TASK |                           
1596 -                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);                                                   
1597 -            info.container = ItemInfo.NO_ID;                                                                      
1598 -            mWorkspace.addApplicationShortcut(info, layout, container, screenId, cellXY[0], cellXY[1],            
1599 -                    isWorkspaceLocked(), cellX, cellY);                                                           
1600 -        } else {                                                                                                  
1601 -            Log.e(TAG, "Couldn't find ActivityInfo for selected application: " + data);                           
1602 -        }                                                                                                         
1603      }                                                                                                             
1604                                                                                                                    
1605      /**                                                                                                           
1606       * Add a shortcut to the workspace.                                                                           
1607       *                                                                                                            
1608       * @param data The intent describing the shortcut.                                                            
1609       * @param cellInfo The position on screen where to create the shortcut.                                       
1610       */                                                                                                           
1611      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1612              int cellY) {                                                                                          
1613          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1614          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1615          CellLayout layout = getCellLayout(container, screenId);                                                   
1616                                                                                                                    
1617          boolean foundCellSpan = false;                                                                            
1618                                                                                                                    
1619          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);                                      
1620          if (info == null) {                                                                                       
1621              return;                                                                                               
1622          }                                                                                                         
1623          final View view = createShortcut(info);                                                                   
1624                                                                                                                    
1625          // First we check if we already know the exact location where we want to add this item.                   
1626          if (cellX >= 0 && cellY >= 0) {                                                                           
1627              cellXY[0] = cellX;                                                                                    
1628              cellXY[1] = cellY;                                                                                    
1629              foundCellSpan = true;                                                                                 
1630                                                                                                                    
1631              // If appropriate, either create a folder or add to an existing folder                                
1632              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1633                      true, null,null)) {                                                                           
1634                  return;                                                                                           
1635              }                                                                                                     
1636              DragObject dragObject = new DragObject();                                                             
1637              dragObject.dragInfo = info;                                                                           
1638              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1639                      true)) {                                                                                      
1640                  return;                                                                                           
1641              }                                                                                                     
1642          } else if (touchXY != null) {                                                                             
1643              // when dragging and dropping, just find the closest free spot                                        
1644              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1645              foundCellSpan = (result != null);                                                                     
1646          } else {                                                                                                  
1647              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1648          }                                                                                                         
1649                                                                                                                    
1650          if (!foundCellSpan) {                                                                                     
1651              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1652              return;                                                                                               
1653          }                                                                                                         
1654                                                                                                                    
1655          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1656                                                                                                                    
1657          if (!mRestoring) {                                                                                        
1658              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1659                      isWorkspaceLocked());                                                                         
1660          }                                                                                                         
1661      }                                                                                                             
1662                                                                                                                    
1663      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1664              int minHeight) {                                                                                      
1665          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1666          // We want to account for the extra amount of padding that we are adding to the widget                    
1667          // to ensure that it gets the full amount of space that it has requested                                  
1668          int requiredWidth = minWidth + padding.left + padding.right;                                              
1669          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1670          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1671      }                                                                                                             
1672                                                                                                                    
1673      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1674          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1675      }                                                                                                             
1676                                                                                                                    
1677      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1678          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1679      }                                                                                                             
1680                                                                                                                    
1681      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1682          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1683      }                                                                                                             
1684                                                                                                                    
1685      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1686          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1687                  info.minResizeHeight);                                                                            
1688      }                                                                                                             
1689                                                                                                                    
1690      /**                                                                                                           
1691       * Add a widget to the workspace.                                                                             
1692       *                                                                                                            
1693       * @param appWidgetId The app widget id                                                                       
1694       * @param cellInfo The position on screen where to create the widget.                                         
1695       */                                                                                                           
1696      private void completeAddAppWidget(final int appWidgetId, long container, long screenId,                       
1697              AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {                                    
1698          if (appWidgetInfo == null) {                                                                              
1699              appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                                      
1700          }                                                                                                         
1701                                                                                                                    
1702          // Calculate the grid spans needed to fit this widget                                                     
1703          CellLayout layout = getCellLayout(container, screenId);                                                   
1704                                                                                                                    
1705          int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);                                               
1706          int[] spanXY = getSpanForWidget(this, appWidgetInfo);                                                     
1707                                                                                                                    
1708          // Try finding open space on Launcher screen                                                              
1709          // We have saved the position to which the widget was dragged-- this really only matters                  
1710          // if we are placing widgets on a "spring-loaded" screen                                                  
1711          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1712          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1713          int[] finalSpan = new int[2];                                                                             
1714          boolean foundCellSpan = false;                                                                            
1715          if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) {                                           
1716              cellXY[0] = mPendingAddInfo.cellX;                                                                    
1717              cellXY[1] = mPendingAddInfo.cellY;                                                                    
1718              spanXY[0] = mPendingAddInfo.spanX;                                                                    
1719              spanXY[1] = mPendingAddInfo.spanY;                                                                    
1720              foundCellSpan = true;                                                                                 
1721          } else if (touchXY != null) {                                                                             
1722              // when dragging and dropping, just find the closest free spot                                        
1723              int[] result = layout.findNearestVacantArea(                                                          
1724                      touchXY[0], touchXY[1], minSpanXY[0], minSpanXY[1], spanXY[0],                                
1725                      spanXY[1], cellXY, finalSpan);                                                                
1726              spanXY[0] = finalSpan[0];                                                                             
1727              spanXY[1] = finalSpan[1];                                                                             
1728              foundCellSpan = (result != null);                                                                     
1729          } else {                                                                                                  
1730              foundCellSpan = layout.findCellForSpan(cellXY, minSpanXY[0], minSpanXY[1]);                           
1731          }                                                                                                         
1732                                                                                                                    
1733          if (!foundCellSpan) {                                                                                     
1734              if (appWidgetId != -1) {                                                                              
1735                  // Deleting an app widget ID is a void call but writes to disk before returning                   
1736                  // to the caller...                                                                               
1737                  new AsyncTask<Void, Void, Void>() {                                                               
1738                      public Void doInBackground(Void ... args) {                                                   
1739                          mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                            
1740                          return null;                                                                              
1741                      }                                                                                             
1742                  }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                 
1743              }                                                                                                     
1744              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1745              return;                                                                                               
1746          }                                                                                                         
1747                                                                                                                    
1748          // Build Launcher-specific widget info and save to database                                               
1749          LauncherAppWidgetInfo launcherInfo = new LauncherAppWidgetInfo(appWidgetId,                               
1750                  appWidgetInfo.provider);                                                                          
1751          launcherInfo.spanX = spanXY[0];                                                                           
1752          launcherInfo.spanY = spanXY[1];                                                                           
1753          launcherInfo.minSpanX = mPendingAddInfo.minSpanX;                                                         
1754          launcherInfo.minSpanY = mPendingAddInfo.minSpanY;                                                         
1755 +        launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1756                                                                                                                    
1757          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1758                  container, screenId, cellXY[0], cellXY[1], false);                                                
1759                                                                                                                    
1760          if (!mRestoring) {                                                                                        
1761              if (hostView == null) {                                                                               
1762                  // Perform actual inflation because we're live                                                    
1763                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);              
1764                  launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo);                                   
1765              } else {                                                                                              
1766                  // The AppWidgetHostView has already been inflated and instantiated                               
1767                  launcherInfo.hostView = hostView;                                                                 
1768              }                                                                                                     
1769                                                                                                                    
1770              launcherInfo.hostView.setTag(launcherInfo);                                                           
1771              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1772              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1773                                                                                                                    
1774              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],              
1775                      launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                                 
1776                                                                                                                    
1777              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1778          }                                                                                                         
1779          resetAddInfo();                                                                                           
1780      }                                                                                                             
1781                                                                                                                    
1782      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1783          @Override                                                                                                 
1784          public void onReceive(Context context, Intent intent) {                                                   
1785              final String action = intent.getAction();                                                             
1786              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1787                  mUserPresent = false;                                                                             
1788                  mDragLayer.clearAllResizeFrames();                                                                
1789                  updateRunning();                                                                                  
1790                                                                                                                    
1791                  // Reset AllApps to its initial state only if we are not in the middle of                         
1792                  // processing a multi-step drop                                                                   
1793                  if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               
1794                      showWorkspace(false);                                                                         
1795                  }                                                                                                 
1796              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1797                  mUserPresent = true;                                                                              
1798                  updateRunning();                                                                                  
1799              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1800                  mModel.resetLoadedState(false, true);                                                             
1801                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1802                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1803              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1804                  mModel.resetLoadedState(false, true);                                                             
1805                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1806                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1807                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1808 +            } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1809 +                    || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1810 +                getModel().forceReload();                                                                         
1811              }                                                                                                     
1812          }                                                                                                         
1813      };                                                                                                            
1814                                                                                                                    
1815      @Override                                                                                                     
1816      public void onAttachedToWindow() {                                                                            
1817          super.onAttachedToWindow();                                                                               
1818                                                                                                                    
1819          // Listen for broadcasts related to user-presence                                                         
1820          final IntentFilter filter = new IntentFilter();                                                           
1821          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1822          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1823 +        // For handling managed profiles                                                                          
1824 +        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1825 +        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1826          if (ENABLE_DEBUG_INTENTS) {                                                                               
1827              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1828              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1829          }                                                                                                         
1830          registerReceiver(mReceiver, filter);                                                                      
1831          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1832 +        setupTransparentSystemBarsForLmp();                                                                       
1833          mAttached = true;                                                                                         
1834          mVisible = true;                                                                                          
1835 +    }                                                                                                             
1836 +                                                                                                                  
1837 +    /**                                                                                                           
1838 +     * Sets up transparent navigation and status bars in LMP.                                                     
1839 +     * This method is a no-op for other platform versions.                                                        
1840 +     */                                                                                                           
1841 +    @TargetApi(19)                                                                                                
1842 +    private void setupTransparentSystemBarsForLmp() {                                                             
1843 +        // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1844 +        // Currently we use reflection to access the flags and the API to set the transparency                    
1845 +        // on the System bars.                                                                                    
1846 +        if (Utilities.isLmpOrAbove()) {                                                                           
1847 +            try {                                                                                                 
1848 +                getWindow().getAttributes().systemUiVisibility |=                                                 
1849 +                        (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1850 +                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1851 +                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1852 +                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1853 +                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1854 +                Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1855 +                        "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1856 +                getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1857 +                                                                                                                  
1858 +                Method setStatusBarColorMethod =                                                                  
1859 +                        Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1860 +                Method setNavigationBarColorMethod =                                                              
1861 +                        Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1862 +                setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1863 +                setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1864 +            } catch (NoSuchFieldException e) {                                                                    
1865 +                Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1866 +            } catch (NoSuchMethodException ex) {                                                                  
1867 +                Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1868 +            } catch (IllegalAccessException e) {                                                                  
1869 +                Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1870 +            } catch (IllegalArgumentException e) {                                                                
1871 +                Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1872 +            } catch (InvocationTargetException e) {                                                               
1873 +                Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1874 +            } finally {}                                                                                          
1875 +        }                                                                                                         
1876      }                                                                                                             
1877                                                                                                                    
1878      @Override                                                                                                     
1879      public void onDetachedFromWindow() {                                                                          
1880          super.onDetachedFromWindow();                                                                             
1881          mVisible = false;                                                                                         
1882                                                                                                                    
1883          if (mAttached) {                                                                                          
1884              unregisterReceiver(mReceiver);                                                                        
1885              mAttached = false;                                                                                    
1886          }                                                                                                         
1887          updateRunning();                                                                                          
1888      }                                                                                                             
1889                                                                                                                    
1890      public void onWindowVisibilityChanged(int visibility) {                                                       
1891          mVisible = visibility == View.VISIBLE;                                                                    
1892          updateRunning();                                                                                          
1893          // The following code used to be in onResume, but it turns out onResume is called when                    
1894          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1895          // is a more appropriate event to handle                                                                  
1896          if (mVisible) {                                                                                           
1897              mAppsCustomizeTabHost.onWindowVisible();                                                              
1898              if (!mWorkspaceLoading) {                                                                             
1899                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1900                  // We want to let Launcher draw itself at least once before we force it to build                  
1901                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1902                  // apps is nice and speedy.                                                                       
1903                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1904                      private boolean mStarted = false;                                                             
1905                      public void onDraw() {                                                                        
1906                          if (mStarted) return;                                                                     
1907                          mStarted = true;                                                                          
1908                          // We delay the layer building a bit in order to give                                     
1909                          // other message processing a time to run.  In particular                                 
1910                          // this avoids a delay in hiding the IME if it was                                        
1911                          // currently shown, because doing that may involve                                        
1912                          // some communication back with the app.                                                  
1913                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1914                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1915                          mWorkspace.post(new Runnable() {                                                          
1916                                  public void run() {                                                               
1917                                      if (mWorkspace != null &&                                                     
1918                                              mWorkspace.getViewTreeObserver() != null) {                           
1919                                          mWorkspace.getViewTreeObserver().                                         
1920                                                  removeOnDrawListener(listener);                                   
1921                                      }                                                                             
1922                                  }                                                                                 
1923                              });                                                                                   
1924                          return;                                                                                   
1925                      }                                                                                             
1926                  });                                                                                               
1927              }                                                                                                     
1928 -            // When Launcher comes back to foreground, a different Activity might be responsible for              
1929 -            // the app market intent, so refresh the icon                                                         
1930 -            if (!DISABLE_MARKET_BUTTON) {                                                                         
1931 -                updateAppMarketIcon();                                                                            
1932 -            }                                                                                                     
1933              clearTypedText();                                                                                     
1934          }                                                                                                         
1935      }                                                                                                             
1936                                                                                                                    
1937      private void sendAdvanceMessage(long delay) {                                                                 
1938          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1939          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1940          mHandler.sendMessageDelayed(msg, delay);                                                                  
1941          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1942      }                                                                                                             
1943                                                                                                                    
1944      private void updateRunning() {                                                                                
1945          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1946          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1947              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1948              if (autoAdvanceRunning) {                                                                             
1949                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1950                  sendAdvanceMessage(delay);                                                                        
1951              } else {                                                                                              
1952                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1953                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1954                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1955                  }                                                                                                 
1956                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1957                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1958              }                                                                                                     
1959          }                                                                                                         
1960      }                                                                                                             
1961                                                                                                                    
1962      private final Handler mHandler = new Handler() {                                                              
1963          @Override                                                                                                 
1964          public void handleMessage(Message msg) {                                                                  
1965              if (msg.what == ADVANCE_MSG) {                                                                        
1966                  int i = 0;                                                                                        
1967                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1968                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1969                      final int delay = mAdvanceStagger * i;                                                        
1970                      if (v instanceof Advanceable) {                                                               
1971                         postDelayed(new Runnable() {                                                               
1972                             public void run() {                                                                    
1973                                 ((Advanceable) v).advance();                                                       
1974                             }                                                                                      
1975                         }, delay);                                                                                 
1976                      }                                                                                             
1977                      i++;                                                                                          
1978                  }                                                                                                 
1979                  sendAdvanceMessage(mAdvanceInterval);                                                             
1980              }                                                                                                     
1981          }                                                                                                         
1982      };                                                                                                            
1983                                                                                                                    
1984      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1985          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1986          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1987          if (v instanceof Advanceable) {                                                                           
1988              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1989              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1990              updateRunning();                                                                                      
1991          }                                                                                                         
1992      }                                                                                                             
1993                                                                                                                    
1994      void removeWidgetToAutoAdvance(View hostView) {                                                               
1995          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1996              mWidgetsToAdvance.remove(hostView);                                                                   
1997              updateRunning();                                                                                      
1998          }                                                                                                         
1999      }                                                                                                             
2000                                                                                                                    
2001      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
2002          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
2003          launcherInfo.hostView = null;                                                                             
2004      }                                                                                                             
2005                                                                                                                    
2006      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
2007          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
2008          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
2009      }                                                                                                             
2010                                                                                                                    
2011      public DragLayer getDragLayer() {                                                                             
2012          return mDragLayer;                                                                                        
2013      }                                                                                                             
2014                                                                                                                    
2015      public Workspace getWorkspace() {                                                                             
2016          return mWorkspace;                                                                                        
2017      }                                                                                                             
2018                                                                                                                    
2019      public Hotseat getHotseat() {                                                                                 
2020          return mHotseat;                                                                                          
2021      }                                                                                                             
2022                                                                                                                    
2023      public ViewGroup getOverviewPanel() {                                                                         
2024          return mOverviewPanel;                                                                                    
2025      }                                                                                                             
2026                                                                                                                    
2027      public SearchDropTargetBar getSearchBar() {                                                                   
2028          return mSearchDropTargetBar;                                                                              
2029      }                                                                                                             
2030                                                                                                                    
2031      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
2032          return mAppWidgetHost;                                                                                    
2033      }                                                                                                             
2034                                                                                                                    
2035      public LauncherModel getModel() {                                                                             
2036          return mModel;                                                                                            
2037      }                                                                                                             
2038                                                                                                                    
2039 -    public LauncherClings getLauncherClings() {                                                                   
2040 -        return mLauncherClings;                                                                                   
2041 -    }                                                                                                             
2042 -                                                                                                                  
2043      protected SharedPreferences getSharedPrefs() {                                                                
2044          return mSharedPrefs;                                                                                      
2045      }                                                                                                             
2046                                                                                                                    
2047      public void closeSystemDialogs() {                                                                            
2048          getWindow().closeAllPanels();                                                                             
2049                                                                                                                    
2050          // Whatever we were doing is hereby canceled.                                                             
2051 -        mWaitingForResult = false;                                                                                
2052 +        setWaitingForResult(false);                                                                               
2053      }                                                                                                             
2054                                                                                                                    
2055      @Override                                                                                                     
2056      protected void onNewIntent(Intent intent) {                                                                   
2057          long startTime = 0;                                                                                       
2058          if (DEBUG_RESUME_TIME) {                                                                                  
2059              startTime = System.currentTimeMillis();                                                               
2060          }                                                                                                         
2061          super.onNewIntent(intent);                                                                                
2062                                                                                                                    
2063          // Close the menu                                                                                         
2064          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
2065              // also will cancel mWaitingForResult.                                                                
2066              closeSystemDialogs();                                                                                 
2067                                                                                                                    
2068              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
2069                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
2070                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
2071                                                                                                                    
2072              if (mWorkspace == null) {                                                                             
2073                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
2074                  return;                                                                                           
2075              }                                                                                                     
2076              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2077              // In all these cases, only animate if we're already on home                                          
2078              mWorkspace.exitWidgetResizeMode();                                                                    
2079              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
2080                      openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {                              
2081                  mWorkspace.moveToDefaultScreen(true);                                                             
2082              }                                                                                                     
2083                                                                                                                    
2084              closeFolder();                                                                                        
2085              exitSpringLoadedDragMode();                                                                           
2086                                                                                                                    
2087              // If we are already on home, then just animate back to the workspace,                                
2088              // otherwise, just wait until onResume to set the state back to Workspace                             
2089              if (alreadyOnHome) {                                                                                  
2090                  showWorkspace(true);                                                                              
2091              } else {                                                                                              
2092                  mOnResumeState = State.WORKSPACE;                                                                 
2093              }                                                                                                     
2094                                                                                                                    
2095              final View v = getWindow().peekDecorView();                                                           
2096              if (v != null && v.getWindowToken() != null) {                                                        
2097                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
2098                          INPUT_METHOD_SERVICE);                                                                    
2099                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
2100              }                                                                                                     
2101                                                                                                                    
2102              // Reset the apps customize page                                                                      
2103              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
2104                  mAppsCustomizeTabHost.reset();                                                                    
2105              }                                                                                                     
2106                                                                                                                    
2107              onHomeIntent();                                                                                       
2108          }                                                                                                         
2109                                                                                                                    
2110          if (DEBUG_RESUME_TIME) {                                                                                  
2111              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
2112          }                                                                                                         
2113      }                                                                                                             
2114                                                                                                                    
2115      /**                                                                                                           
2116       * Override point for subclasses to prevent movement to the default screen when the home                      
2117       * button is pressed. Used (for example) in GEL, to prevent movement during a search.                         
2118       */                                                                                                           
2119      protected boolean shouldMoveToDefaultScreenOnHomeIntent() {                                                   
2120          return true;                                                                                              
2121      }                                                                                                             
2122                                                                                                                    
2123      /**                                                                                                           
2124       * Override point for subclasses to provide custom behaviour for when a home intent is fired.                 
2125       */                                                                                                           
2126      protected void onHomeIntent() {                                                                               
2127          // Do nothing                                                                                             
2128      }                                                                                                             
2129                                                                                                                    
2130      @Override                                                                                                     
2131      public void onRestoreInstanceState(Bundle state) {                                                            
2132          super.onRestoreInstanceState(state);                                                                      
2133          for (int page: mSynchronouslyBoundPages) {                                                                
2134              mWorkspace.restoreInstanceStateForChild(page);                                                        
2135          }                                                                                                         
2136      }                                                                                                             
2137                                                                                                                    
2138      @Override                                                                                                     
2139      protected void onSaveInstanceState(Bundle outState) {                                                         
2140          if (mWorkspace.getChildCount() > 0) {                                                                     
2141              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
2142                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
2143          }                                                                                                         
2144          super.onSaveInstanceState(outState);                                                                      
2145                                                                                                                    
2146          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
2147          // We close any open folder since it will not be re-opened, and we need to make sure                      
2148          // this state is reflected.                                                                               
2149          closeFolder();                                                                                            
2150                                                                                                                    
2151          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
2152                  mWaitingForResult) {                                                                              
2153              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
2154              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
2155              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
2156              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
2157              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
2158              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
2159              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
2160              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2161          }                                                                                                         
2162                                                                                                                    
2163          if (mFolderInfo != null && mWaitingForResult) {                                                           
2164              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2165              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2166          }                                                                                                         
2167                                                                                                                    
2168          // Save the current AppsCustomize tab                                                                     
2169          if (mAppsCustomizeTabHost != null) {                                                                      
2170              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2171              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2172              if (currentTabTag != null) {                                                                          
2173                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
2174              }                                                                                                     
2175              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2176              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2177          }                                                                                                         
2178          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2179      }                                                                                                             
2180                                                                                                                    
2181      @Override                                                                                                     
2182      public void onDestroy() {                                                                                     
2183          super.onDestroy();                                                                                        
2184                                                                                                                    
2185          // Remove all pending runnables                                                                           
2186          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2187          mHandler.removeMessages(0);                                                                               
2188          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2189                                                                                                                    
2190          // Stop callbacks from LauncherModel                                                                      
2191          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2192 -        mModel.stopLoader();                                                                                      
2193 -        app.setLauncher(null);                                                                                    
2194 +                                                                                                                  
2195 +        // It's possible to receive onDestroy after a new Launcher activity has                                   
2196 +        // been created. In this case, don't interfere with the new Launcher.                                     
2197 +        if (mModel.isCurrentCallbacks(this)) {                                                                    
2198 +            mModel.stopLoader();                                                                                  
2199 +            app.setLauncher(null);                                                                                
2200 +        }                                                                                                         
2201                                                                                                                    
2202          try {                                                                                                     
2203              mAppWidgetHost.stopListening();                                                                       
2204          } catch (NullPointerException ex) {                                                                       
2205              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2206          }                                                                                                         
2207          mAppWidgetHost = null;                                                                                    
2208                                                                                                                    
2209          mWidgetsToAdvance.clear();                                                                                
2210                                                                                                                    
2211          TextKeyListener.getInstance().release();                                                                  
2212                                                                                                                    
2213          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2214          // to prevent leaking Launcher activities on orientation change.                                          
2215          if (mModel != null) {                                                                                     
2216              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2217          }                                                                                                         
2218                                                                                                                    
2219          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2220          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2221                                                                                                                    
2222          mDragLayer.clearAllResizeFrames();                                                                        
2223          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2224          mWorkspace.removeAllWorkspaceScreens();                                                                   
2225          mWorkspace = null;                                                                                        
2226          mDragController = null;                                                                                   
2227                                                                                                                    
2228 +        PackageInstallerCompat.getInstance(this).onStop();                                                        
2229          LauncherAnimUtils.onDestroyActivity();                                                                    
2230      }                                                                                                             
2231                                                                                                                    
2232      public DragController getDragController() {                                                                   
2233          return mDragController;                                                                                   
2234      }                                                                                                             
2235                                                                                                                    
2236      @Override                                                                                                     
2237      public void startActivityForResult(Intent intent, int requestCode) {                                          
2238 -        if (requestCode >= 0) mWaitingForResult = true;                                                           
2239 +        if (requestCode >= 0) {                                                                                   
2240 +            setWaitingForResult(true);                                                                            
2241 +        }                                                                                                         
2242          super.startActivityForResult(intent, requestCode);                                                        
2243      }                                                                                                             
2244                                                                                                                    
2245      /**                                                                                                           
2246       * Indicates that we want global search for this activity by setting the globalSearch                         
2247       * argument for {@link #startSearch} to true.                                                                 
2248       */                                                                                                           
2249      @Override                                                                                                     
2250      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2251              Bundle appSearchData, boolean globalSearch) {                                                         
2252                                                                                                                    
2253          showWorkspace(true);                                                                                      
2254                                                                                                                    
2255          if (initialQuery == null) {                                                                               
2256              // Use any text typed in the launcher as the initial query                                            
2257              initialQuery = getTypedText();                                                                        
2258          }                                                                                                         
2259          if (appSearchData == null) {                                                                              
2260              appSearchData = new Bundle();                                                                         
2261              appSearchData.putString("source", "launcher-search");                                                 
2262          }                                                                                                         
2263          Rect sourceBounds = new Rect();                                                                           
2264          if (mSearchDropTargetBar != null) {                                                                       
2265              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2266          }                                                                                                         
2267                                                                                                                    
2268 -        startSearch(initialQuery, selectInitialQuery,                                                             
2269 +        boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2270                  appSearchData, sourceBounds);                                                                     
2271 -    }                                                                                                             
2272 -                                                                                                                  
2273 -    public void startSearch(String initialQuery,                                                                  
2274 +        if (clearTextImmediately) {                                                                               
2275 +            clearTypedText();                                                                                     
2276 +        }                                                                                                         
2277 +    }                                                                                                             
2278 +                                                                                                                  
2279 +    /**                                                                                                           
2280 +     * Start a text search.                                                                                       
2281 +     *                                                                                                            
2282 +     * @return {@code true} if the search will start immediately, so any further keypresses                       
2283 +     * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2284 +     * to buffer keypresses.                                                                                      
2285 +     */                                                                                                           
2286 +    public boolean startSearch(String initialQuery,                                                               
2287              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2288          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2289                  appSearchData, sourceBounds);                                                                     
2290 +        return false;                                                                                             
2291      }                                                                                                             
2292                                                                                                                    
2293      /**                                                                                                           
2294       * Starts the global search activity. This code is a copied from SearchManager                                
2295       */                                                                                                           
2296      private void startGlobalSearch(String initialQuery,                                                           
2297              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2298          final SearchManager searchManager =                                                                       
2299              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2300          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2301          if (globalSearchActivity == null) {                                                                       
2302              Log.w(TAG, "No global search activity found.");                                                       
2303              return;                                                                                               
2304          }                                                                                                         
2305          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2306          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2307          intent.setComponent(globalSearchActivity);                                                                
2308          // Make sure that we have a Bundle to put source in                                                       
2309          if (appSearchData == null) {                                                                              
2310              appSearchData = new Bundle();                                                                         
2311          } else {                                                                                                  
2312              appSearchData = new Bundle(appSearchData);                                                            
2313          }                                                                                                         
2314          // Set source to package name of app that starts global search, if not set already.                       
2315          if (!appSearchData.containsKey("source")) {                                                               
2316              appSearchData.putString("source", getPackageName());                                                  
2317          }                                                                                                         
2318          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2319          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2320              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2321          }                                                                                                         
2322          if (selectInitialQuery) {                                                                                 
2323              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2324          }                                                                                                         
2325          intent.setSourceBounds(sourceBounds);                                                                     
2326          try {                                                                                                     
2327              startActivity(intent);                                                                                
2328          } catch (ActivityNotFoundException ex) {                                                                  
2329              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2330          }                                                                                                         
2331      }                                                                                                             
2332                                                                                                                    
2333      public boolean isOnCustomContent() {                                                                          
2334          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2335      }                                                                                                             
2336                                                                                                                    
2337      @Override                                                                                                     
2338      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2339          super.onPrepareOptionsMenu(menu);                                                                         
2340          if (!isOnCustomContent()) {                                                                               
2341              // Close any open folders                                                                             
2342              closeFolder();                                                                                        
2343              // Stop resizing any widgets                                                                          
2344              mWorkspace.exitWidgetResizeMode();                                                                    
2345              if (!mWorkspace.isInOverviewMode()) {                                                                 
2346                  // Show the overview mode                                                                         
2347                  showOverviewMode(true);                                                                           
2348              } else {                                                                                              
2349                  showWorkspace(true);                                                                              
2350              }                                                                                                     
2351          }                                                                                                         
2352          return false;                                                                                             
2353      }                                                                                                             
2354                                                                                                                    
2355      @Override                                                                                                     
2356      public boolean onSearchRequested() {                                                                          
2357          startSearch(null, false, null, true);                                                                     
2358          // Use a custom animation for launching search                                                            
2359          return true;                                                                                              
2360      }                                                                                                             
2361                                                                                                                    
2362      public boolean isWorkspaceLocked() {                                                                          
2363          return mWorkspaceLoading || mWaitingForResult;                                                            
2364      }                                                                                                             
2365                                                                                                                    
2366 +    public boolean isWorkspaceLoading() {                                                                         
2367 +        return mWorkspaceLoading;                                                                                 
2368 +    }                                                                                                             
2369 +                                                                                                                  
2370 +    private void setWorkspaceLoading(boolean value) {                                                             
2371 +        boolean isLocked = isWorkspaceLocked();                                                                   
2372 +        mWorkspaceLoading = value;                                                                                
2373 +        if (isLocked != isWorkspaceLocked()) {                                                                    
2374 +            onWorkspaceLockedChanged();                                                                           
2375 +        }                                                                                                         
2376 +    }                                                                                                             
2377 +                                                                                                                  
2378 +    private void setWaitingForResult(boolean value) {                                                             
2379 +        boolean isLocked = isWorkspaceLocked();                                                                   
2380 +        mWaitingForResult = value;                                                                                
2381 +        if (isLocked != isWorkspaceLocked()) {                                                                    
2382 +            onWorkspaceLockedChanged();                                                                           
2383 +        }                                                                                                         
2384 +    }                                                                                                             
2385 +                                                                                                                  
2386 +    protected void onWorkspaceLockedChanged() { }                                                                 
2387 +                                                                                                                  
2388      private void resetAddInfo() {                                                                                 
2389          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2390          mPendingAddInfo.screenId = -1;                                                                            
2391          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2392          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2393          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2394          mPendingAddInfo.dropPos = null;                                                                           
2395      }                                                                                                             
2396                                                                                                                    
2397      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2398              final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {                     
2399          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2400      }                                                                                                             
2401                                                                                                                    
2402      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2403              final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int                   
2404              delay) {                                                                                              
2405          if (appWidgetInfo.configure != null) {                                                                    
2406              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2407              mPendingAddWidgetId = appWidgetId;                                                                    
2408                                                                                                                    
2409              // Launch over to configure widget, if needed                                                         
2410 -            Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);                              
2411 -            intent.setComponent(appWidgetInfo.configure);                                                         
2412 -            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                    
2413 -            Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_APPWIDGET);                       
2414 +            mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2415 +                    mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2416 +                                                                                                                  
2417          } else {                                                                                                  
2418              // Otherwise just add it                                                                              
2419              Runnable onComplete = new Runnable() {                                                                
2420                  @Override                                                                                         
2421                  public void run() {                                                                               
2422                      // Exit spring loaded mode if necessary after adding the widget                               
2423                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2424                              null);                                                                                
2425                  }                                                                                                 
2426              };                                                                                                    
2427              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2428                      appWidgetInfo);                                                                               
2429 -            mWorkspace.removeExtraEmptyScreen(true, onComplete, delay, false);                                    
2430 +            mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2431          }                                                                                                         
2432      }                                                                                                             
2433                                                                                                                    
2434      protected void moveToCustomContentScreen(boolean animate) {                                                   
2435          // Close any folders that may be open.                                                                    
2436          closeFolder();                                                                                            
2437          mWorkspace.moveToCustomContentScreen(animate);                                                            
2438      }                                                                                                             
2439      /**                                                                                                           
2440       * Process a shortcut drop.                                                                                   
2441       *                                                                                                            
2442       * @param componentName The name of the component                                                             
2443       * @param screenId The ID of the screen where it should be added                                              
2444       * @param cell The cell it should be added to, optional                                                       
2445       * @param position The location on the screen where it was dropped, optional                                  
2446       */                                                                                                           
2447      void processShortcutFromDrop(ComponentName componentName, long container, long screenId,                      
2448              int[] cell, int[] loc) {                                                                              
2449          resetAddInfo();                                                                                           
2450          mPendingAddInfo.container = container;                                                                    
2451          mPendingAddInfo.screenId = screenId;                                                                      
2452          mPendingAddInfo.dropPos = loc;                                                                            
2453                                                                                                                    
2454          if (cell != null) {                                                                                       
2455              mPendingAddInfo.cellX = cell[0];                                                                      
2456              mPendingAddInfo.cellY = cell[1];                                                                      
2457          }                                                                                                         
2458                                                                                                                    
2459          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2460          createShortcutIntent.setComponent(componentName);                                                         
2461          processShortcut(createShortcutIntent);                                                                    
2462      }                                                                                                             
2463                                                                                                                    
2464      /**                                                                                                           
2465       * Process a widget drop.                                                                                     
2466       *                                                                                                            
2467       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2468       * @param screenId The ID of the screen where it should be added                                              
2469       * @param cell The cell it should be added to, optional                                                       
2470       * @param position The location on the screen where it was dropped, optional                                  
2471       */                                                                                                           
2472      void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                           
2473              int[] cell, int[] span, int[] loc) {                                                                  
2474          resetAddInfo();                                                                                           
2475          mPendingAddInfo.container = info.container = container;                                                   
2476          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2477          mPendingAddInfo.dropPos = loc;                                                                            
2478          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2479          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2480                                                                                                                    
2481          if (cell != null) {                                                                                       
2482              mPendingAddInfo.cellX = cell[0];                                                                      
2483              mPendingAddInfo.cellY = cell[1];                                                                      
2484          }                                                                                                         
2485          if (span != null) {                                                                                       
2486              mPendingAddInfo.spanX = span[0];                                                                      
2487              mPendingAddInfo.spanY = span[1];                                                                      
2488          }                                                                                                         
2489                                                                                                                    
2490          AppWidgetHostView hostView = info.boundWidget;                                                            
2491          int appWidgetId;                                                                                          
2492          if (hostView != null) {                                                                                   
2493              appWidgetId = hostView.getAppWidgetId();                                                              
2494              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2495          } else {                                                                                                  
2496              // In this case, we either need to start an activity to get permission to bind                        
2497              // the widget, or we need to start an activity to configure the widget, or both.                      
2498              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2499              Bundle options = info.bindOptions;                                                                    
2500                                                                                                                    
2501 -            boolean success = false;                                                                              
2502 -            if (options != null) {                                                                                
2503 -                success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,                                 
2504 -                        info.componentName, options);                                                             
2505 -            } else {                                                                                              
2506 -                success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,                                 
2507 -                        info.componentName);                                                                      
2508 -            }                                                                                                     
2509 +            boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2510 +                    appWidgetId, info.info, options);                                                             
2511              if (success) {                                                                                        
2512                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2513              } else {                                                                                              
2514                  mPendingAddWidgetInfo = info.info;                                                                
2515                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2516                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2517                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2518 +                mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2519 +                    .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2520                  // TODO: we need to make sure that this accounts for the options bundle.                          
2521                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2522                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2523              }                                                                                                     
2524          }                                                                                                         
2525      }                                                                                                             
2526                                                                                                                    
2527      void processShortcut(Intent intent) {                                                                         
2528 -        // Handle case where user selected "Applications"                                                         
2529 -        String applicationName = getResources().getString(R.string.group_applications);                           
2530 -        String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);                                  
2531 -                                                                                                                  
2532 -        if (applicationName != null && applicationName.equals(shortcutName)) {                                    
2533 -            Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);                                             
2534 -            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);                                                     
2535 -                                                                                                                  
2536 -            Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);                                          
2537 -            pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);                                                 
2538 -            pickIntent.putExtra(Intent.EXTRA_TITLE, getText(R.string.title_select_application));                  
2539 -            Utilities.startActivityForResultSafely(this, pickIntent, REQUEST_PICK_APPLICATION);                   
2540 -        } else {                                                                                                  
2541 -            Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                        
2542 -        }                                                                                                         
2543 +        Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2544      }                                                                                                             
2545                                                                                                                    
2546      void processWallpaper(Intent intent) {                                                                        
2547          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2548      }                                                                                                             
2549                                                                                                                    
2550      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2551              int cellY) {                                                                                          
2552          final FolderInfo folderInfo = new FolderInfo();                                                           
2553          folderInfo.title = getText(R.string.folder_name);                                                         
2554                                                                                                                    
2555          // Update the model                                                                                       
2556          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2557                  false);                                                                                           
2558          sFolders.put(folderInfo.id, folderInfo);                                                                  
2559                                                                                                                    
2560          // Create the view                                                                                        
2561          FolderIcon newFolder =                                                                                    
2562              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2563          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2564                  isWorkspaceLocked());                                                                             
2565          // Force measure the new folder icon                                                                      
2566          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2567          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2568          return newFolder;                                                                                         
2569      }                                                                                                             
2570                                                                                                                    
2571      void removeFolder(FolderInfo folder) {                                                                        
2572          sFolders.remove(folder.id);                                                                               
2573 -    }                                                                                                             
2574 -                                                                                                                  
2575 -    protected void startWallpaper() {                                                                             
2576 -        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2577 -        pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2578 -        startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
2579      }                                                                                                             
2580                                                                                                                    
2581      protected ComponentName getWallpaperPickerComponent() {                                                       
2582          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2583      }                                                                                                             
2584                                                                                                                    
2585      /**                                                                                                           
2586       * Registers various content observers. The current implementation registers                                  
2587       * only a favorites observer to keep track of the favorites applications.                                     
2588       */                                                                                                           
2589      private void registerContentObservers() {                                                                     
2590          ContentResolver resolver = getContentResolver();                                                          
2591          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2592                  true, mWidgetObserver);                                                                           
2593      }                                                                                                             
2594                                                                                                                    
2595      @Override                                                                                                     
2596      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2597          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2598              switch (event.getKeyCode()) {                                                                         
2599                  case KeyEvent.KEYCODE_HOME:                                                                       
2600                      return true;                                                                                  
2601                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2602                      if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                                 
2603                          dumpState();                                                                              
2604                          return true;                                                                              
2605                      }                                                                                             
2606                      break;                                                                                        
2607              }                                                                                                     
2608          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2609              switch (event.getKeyCode()) {                                                                         
2610                  case KeyEvent.KEYCODE_HOME:                                                                       
2611                      return true;                                                                                  
2612              }                                                                                                     
2613          }                                                                                                         
2614                                                                                                                    
2615          return super.dispatchKeyEvent(event);                                                                     
2616      }                                                                                                             
2617                                                                                                                    
2618      @Override                                                                                                     
2619      public void onBackPressed() {                                                                                 
2620          if (isAllAppsVisible()) {                                                                                 
2621              if (mAppsCustomizeContent.getContentType() ==                                                         
2622                      AppsCustomizePagedView.ContentType.Applications) {                                            
2623                  showWorkspace(true);                                                                              
2624              } else {                                                                                              
2625                  showOverviewMode(true);                                                                           
2626              }                                                                                                     
2627          } else if (mWorkspace.isInOverviewMode()) {                                                               
2628              mWorkspace.exitOverviewMode(true);                                                                    
2629          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2630              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2631              if (openFolder.isEditingName()) {                                                                     
2632                  openFolder.dismissEditingName();                                                                  
2633              } else {                                                                                              
2634                  closeFolder();                                                                                    
2635              }                                                                                                     
2636          } else {                                                                                                  
2637              mWorkspace.exitWidgetResizeMode();                                                                    
2638                                                                                                                    
2639              // Back button is a no-op here, but give at least some feedback for the button press                  
2640              mWorkspace.showOutlinesTemporarily();                                                                 
2641          }                                                                                                         
2642      }                                                                                                             
2643                                                                                                                    
2644      /**                                                                                                           
2645       * Re-listen when widgets are reset.                                                                          
2646       */                                                                                                           
2647      private void onAppWidgetReset() {                                                                             
2648          if (mAppWidgetHost != null) {                                                                             
2649              mAppWidgetHost.startListening();                                                                      
2650          }                                                                                                         
2651      }                                                                                                             
2652                                                                                                                    
2653      /**                                                                                                           
2654       * Launches the intent referred by the clicked shortcut.                                                      
2655       *                                                                                                            
2656       * @param v The view representing the clicked shortcut.                                                       
2657       */                                                                                                           
2658      public void onClick(View v) {                                                                                 
2659          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2660          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2661          if (v.getWindowToken() == null) {                                                                         
2662              return;                                                                                               
2663          }                                                                                                         
2664                                                                                                                    
2665          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2666              return;                                                                                               
2667          }                                                                                                         
2668                                                                                                                    
2669          if (v instanceof Workspace) {                                                                             
2670              if (mWorkspace.isInOverviewMode()) {                                                                  
2671                  mWorkspace.exitOverviewMode(true);                                                                
2672              }                                                                                                     
2673              return;                                                                                               
2674          }                                                                                                         
2675                                                                                                                    
2676          if (v instanceof CellLayout) {                                                                            
2677              if (mWorkspace.isInOverviewMode()) {                                                                  
2678                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2679              }                                                                                                     
2680          }                                                                                                         
2681                                                                                                                    
2682          Object tag = v.getTag();                                                                                  
2683          if (tag instanceof ShortcutInfo) {                                                                        
2684 -            // Open shortcut                                                                                      
2685 -            final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                     
2686 -            final Intent intent = shortcut.intent;                                                                
2687 -                                                                                                                  
2688 -            // Check for special shortcuts                                                                        
2689 -            if (intent.getComponent() != null) {                                                                  
2690 -                final String shortcutClass = intent.getComponent().getClassName();                                
2691 -                                                                                                                  
2692 -                if (shortcutClass.equals(WidgetAdder.class.getName())) {                                          
2693 -                    onClickAddWidgetButton();                                                                     
2694 -                    return;                                                                                       
2695 -                } else if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                            
2696 -                    MemoryDumpActivity.startDump(this);                                                           
2697 -                    return;                                                                                       
2698 -                } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                           
2699 -                    toggleShowWeightWatcher();                                                                    
2700 -                    return;                                                                                       
2701 -                }                                                                                                 
2702 -            }                                                                                                     
2703 -                                                                                                                  
2704 -            // Start activities                                                                                   
2705 -            int[] pos = new int[2];                                                                               
2706 -            v.getLocationOnScreen(pos);                                                                           
2707 -            intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2708 -                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2709 -                                                                                                                  
2710 -            boolean success = startActivitySafely(v, intent, tag);                                                
2711 -                                                                                                                  
2712 -            mStats.recordLaunch(intent, shortcut);                                                                
2713 -                                                                                                                  
2714 -            if (success && v instanceof BubbleTextView) {                                                         
2715 -                mWaitingForResume = (BubbleTextView) v;                                                           
2716 -                mWaitingForResume.setStayPressed(true);                                                           
2717 -            }                                                                                                     
2718 +            onClickAppShortcut(v);                                                                                
2719          } else if (tag instanceof FolderInfo) {                                                                   
2720              if (v instanceof FolderIcon) {                                                                        
2721 -                FolderIcon fi = (FolderIcon) v;                                                                   
2722 -                handleFolderClick(fi);                                                                            
2723 +                onClickFolderIcon(v);                                                                             
2724              }                                                                                                     
2725          } else if (v == mAllAppsButton) {                                                                         
2726 -            if (isAllAppsVisible()) {                                                                             
2727 -                showWorkspace(true);                                                                              
2728 -            } else {                                                                                              
2729 -                onClickAllAppsButton(v);                                                                          
2730 -            }                                                                                                     
2731 -        }                                                                                                         
2732 +            onClickAllAppsButton(v);                                                                              
2733 +        } else if (tag instanceof AppInfo) {                                                                      
2734 +            startAppShortcutOrInfoActivity(v);                                                                    
2735 +        } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2736 +            if (v instanceof PendingAppWidgetHostView) {                                                          
2737 +                onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2738 +            }                                                                                                     
2739 +        }                                                                                                         
2740 +    }                                                                                                             
2741 +                                                                                                                  
2742 +    public void onClickPagedViewIcon(View v) {                                                                    
2743 +        startAppShortcutOrInfoActivity(v);                                                                        
2744      }                                                                                                             
2745                                                                                                                    
2746      public boolean onTouch(View v, MotionEvent event) {                                                           
2747          return false;                                                                                             
2748 +    }                                                                                                             
2749 +                                                                                                                  
2750 +    /**                                                                                                           
2751 +     * Event handler for the app widget view which has not fully restored.                                        
2752 +     */                                                                                                           
2753 +    public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2754 +        final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2755 +        if (v.isReadyForClickSetup()) {                                                                           
2756 +            int widgetId = info.appWidgetId;                                                                      
2757 +            AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2758 +            if (appWidgetInfo != null) {                                                                          
2759 +                mPendingAddWidgetInfo = appWidgetInfo;                                                            
2760 +                mPendingAddInfo.copyFrom(info);                                                                   
2761 +                mPendingAddWidgetId = widgetId;                                                                   
2762 +                                                                                                                  
2763 +                AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2764 +                        info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2765 +            }                                                                                                     
2766 +        } else if (info.installProgress < 0) {                                                                    
2767 +            // The install has not been queued                                                                    
2768 +            final String packageName = info.providerName.getPackageName();                                        
2769 +            showBrokenAppInstallDialog(packageName,                                                               
2770 +                new DialogInterface.OnClickListener() {                                                           
2771 +                    public void onClick(DialogInterface dialog, int id) {                                         
2772 +                        startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2773 +                    }                                                                                             
2774 +                });                                                                                               
2775 +        } else {                                                                                                  
2776 +            // Download has started.                                                                              
2777 +            final String packageName = info.providerName.getPackageName();                                        
2778 +            startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2779 +        }                                                                                                         
2780      }                                                                                                             
2781                                                                                                                    
2782      /**                                                                                                           
2783       * Event handler for the search button                                                                        
2784       *                                                                                                            
2785       * @param v The view that was clicked.                                                                        
2786       */                                                                                                           
2787      public void onClickSearchButton(View v) {                                                                     
2788          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2789                                                                                                                    
2790          onSearchRequested();                                                                                      
2791      }                                                                                                             
2792                                                                                                                    
2793      /**                                                                                                           
2794       * Event handler for the voice button                                                                         
2795       *                                                                                                            
2796       * @param v The view that was clicked.                                                                        
2797       */                                                                                                           
2798      public void onClickVoiceButton(View v) {                                                                      
2799          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2800                                                                                                                    
2801          startVoice();                                                                                             
2802      }                                                                                                             
2803                                                                                                                    
2804      public void startVoice() {                                                                                    
2805          try {                                                                                                     
2806              final SearchManager searchManager =                                                                   
2807                      (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                     
2808              ComponentName activityName = searchManager.getGlobalSearchActivity();                                 
2809              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
2810              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                       
2811              if (activityName != null) {                                                                           
2812                  intent.setPackage(activityName.getPackageName());                                                 
2813              }                                                                                                     
2814              startActivity(null, intent, "onClickVoiceButton");                                                    
2815          } catch (ActivityNotFoundException e) {                                                                   
2816              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
2817              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                       
2818              startActivitySafely(null, intent, "onClickVoiceButton");                                              
2819          }                                                                                                         
2820      }                                                                                                             
2821                                                                                                                    
2822      /**                                                                                                           
2823       * Event handler for the "grid" button that appears on the home screen, which                                 
2824       * enters all apps mode.                                                                                      
2825       *                                                                                                            
2826       * @param v The view that was clicked.                                                                        
2827       */                                                                                                           
2828 -    public void onClickAllAppsButton(View v) {                                                                    
2829 -        showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                                
2830 -    }                                                                                                             
2831 -                                                                                                                  
2832 -    /**                                                                                                           
2833 -     * Event handler for the (Add) Widgets button that appears after a long press                                 
2834 -     * on the home screen.                                                                                        
2835 -     */                                                                                                           
2836 -    protected void onClickAddWidgetButton() {                                                                     
2837 -        showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                      
2838 -    }                                                                                                             
2839 -                                                                                                                  
2840 -    public void onTouchDownAllAppsButton(View v) {                                                                
2841 -        // Provide the same haptic feedback that the system offers for virtual keys.                              
2842 -        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2843 -    }                                                                                                             
2844 -                                                                                                                  
2845 -    public void performHapticFeedbackOnTouchDown(View v) {                                                        
2846 -        // Provide the same haptic feedback that the system offers for virtual keys.                              
2847 -        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2848 -    }                                                                                                             
2849 -                                                                                                                  
2850 -    public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2851 -        if (mHapticFeedbackTouchListener == null) {                                                               
2852 -            mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2853 -                @Override                                                                                         
2854 -                public boolean onTouch(View v, MotionEvent event) {                                               
2855 -                    if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2856 -                        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2857 +    protected void onClickAllAppsButton(View v) {                                                                 
2858 +        if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2859 +        if (isAllAppsVisible()) {                                                                                 
2860 +            showWorkspace(true);                                                                                  
2861 +        } else {                                                                                                  
2862 +            showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2863 +        }                                                                                                         
2864 +    }                                                                                                             
2865 +                                                                                                                  
2866 +    private void showBrokenAppInstallDialog(final String packageName,                                             
2867 +            DialogInterface.OnClickListener onSearchClickListener) {                                              
2868 +        new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))               
2869 +            .setTitle(R.string.abandoned_promises_title)                                                          
2870 +            .setMessage(R.string.abandoned_promise_explanation)                                                   
2871 +            .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2872 +            .setNeutralButton(R.string.abandoned_clean_this,                                                      
2873 +                new DialogInterface.OnClickListener() {                                                           
2874 +                    public void onClick(DialogInterface dialog, int id) {                                         
2875 +                        final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2876 +                        mWorkspace.removeAbandonedPromise(packageName, user);                                     
2877                      }                                                                                             
2878 -                    return false;                                                                                 
2879 -                }                                                                                                 
2880 -            };                                                                                                    
2881 -        }                                                                                                         
2882 -        return mHapticFeedbackTouchListener;                                                                      
2883 -    }                                                                                                             
2884 -                                                                                                                  
2885 -    public void onClickAppMarketButton(View v) {                                                                  
2886 -        if (!DISABLE_MARKET_BUTTON) {                                                                             
2887 -            if (mAppMarketIntent != null) {                                                                       
2888 -                startActivitySafely(v, mAppMarketIntent, "app market");                                           
2889 -            } else {                                                                                              
2890 -                Log.e(TAG, "Invalid app market intent.");                                                         
2891 -            }                                                                                                     
2892 -        }                                                                                                         
2893 -    }                                                                                                             
2894 -                                                                                                                  
2895 -    /**                                                                                                           
2896 -     * Called when the user stops interacting with the launcher.                                                  
2897 -     * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2898 -     */                                                                                                           
2899 -    protected void onInteractionEnd() {}                                                                          
2900 -                                                                                                                  
2901 -    /**                                                                                                           
2902 -     * Called when the user starts interacting with the launcher.                                                 
2903 -     * The possible interactions are:                                                                             
2904 -     *  - open all apps                                                                                           
2905 -     *  - reorder an app shortcut, or a widget                                                                    
2906 -     *  - open the overview mode.                                                                                 
2907 -     * This is a good time to stop doing things that only make sense                                              
2908 -     * when the user is on the homescreen and not doing housekeeping.                                             
2909 -     */                                                                                                           
2910 -    protected void onInteractionBegin() {}                                                                        
2911 -                                                                                                                  
2912 -    void startApplicationDetailsActivity(ComponentName componentName) {                                           
2913 -        String packageName = componentName.getPackageName();                                                      
2914 -        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,                                  
2915 -                Uri.fromParts("package", packageName, null));                                                     
2916 -        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |                         
2917 -                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                       
2918 -        startActivitySafely(null, intent, "startApplicationDetailsActivity");                                     
2919 -    }                                                                                                             
2920 -                                                                                                                  
2921 -    // returns true if the activity was started                                                                   
2922 -    boolean startApplicationUninstallActivity(ComponentName componentName, int flags) {                           
2923 -        if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2924 -            // System applications cannot be installed. For now, show a toast explaining that.                    
2925 -            // We may give them the option of disabling apps this way.                                            
2926 -            int messageId = R.string.uninstall_system_app_text;                                                   
2927 -            Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2928 -            return false;                                                                                         
2929 +                })                                                                                                
2930 +            .create().show();                                                                                     
2931 +        return;                                                                                                   
2932 +    }                                                                                                             
2933 +                                                                                                                  
2934 +    /**                                                                                                           
2935 +     * Event handler for an app shortcut click.                                                                   
2936 +     *                                                                                                            
2937 +     * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2938 +     */                                                                                                           
2939 +    protected void onClickAppShortcut(final View v) {                                                             
2940 +        if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2941 +        Object tag = v.getTag();                                                                                  
2942 +        if (!(tag instanceof ShortcutInfo)) {                                                                     
2943 +            throw new IllegalArgumentException("Input must be a Shortcut");                                       
2944 +        }                                                                                                         
2945 +                                                                                                                  
2946 +        // Open shortcut                                                                                          
2947 +        final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2948 +        final Intent intent = shortcut.intent;                                                                    
2949 +                                                                                                                  
2950 +        // Check for special shortcuts                                                                            
2951 +        if (intent.getComponent() != null) {                                                                      
2952 +            final String shortcutClass = intent.getComponent().getClassName();                                    
2953 +                                                                                                                  
2954 +            if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2955 +                MemoryDumpActivity.startDump(this);                                                               
2956 +                return;                                                                                           
2957 +            } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2958 +                toggleShowWeightWatcher();                                                                        
2959 +                return;                                                                                           
2960 +            }                                                                                                     
2961 +        }                                                                                                         
2962 +                                                                                                                  
2963 +        // Check for abandoned promise                                                                            
2964 +        if ((v instanceof BubbleTextView)                                                                         
2965 +                && shortcut.isPromise()                                                                           
2966 +                && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2967 +            showBrokenAppInstallDialog(                                                                           
2968 +                    shortcut.getTargetComponent().getPackageName(),                                               
2969 +                    new DialogInterface.OnClickListener() {                                                       
2970 +                        public void onClick(DialogInterface dialog, int id) {                                     
2971 +                            startAppShortcutOrInfoActivity(v);                                                    
2972 +                        }                                                                                         
2973 +                    });                                                                                           
2974 +            return;                                                                                               
2975 +        }                                                                                                         
2976 +                                                                                                                  
2977 +        // Start activities                                                                                       
2978 +        startAppShortcutOrInfoActivity(v);                                                                        
2979 +    }                                                                                                             
2980 +                                                                                                                  
2981 +    private void startAppShortcutOrInfoActivity(View v) {                                                         
2982 +        Object tag = v.getTag();                                                                                  
2983 +        final ShortcutInfo shortcut;                                                                              
2984 +        final Intent intent;                                                                                      
2985 +        if (tag instanceof ShortcutInfo) {                                                                        
2986 +            shortcut = (ShortcutInfo) tag;                                                                        
2987 +            intent = shortcut.intent;                                                                             
2988 +            int[] pos = new int[2];                                                                               
2989 +            v.getLocationOnScreen(pos);                                                                           
2990 +            intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2991 +                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2992 +                                                                                                                  
2993 +        } else if (tag instanceof AppInfo) {                                                                      
2994 +            shortcut = null;                                                                                      
2995 +            intent = ((AppInfo) tag).intent;                                                                      
2996          } else {                                                                                                  
2997 -            String packageName = componentName.getPackageName();                                                  
2998 -            String className = componentName.getClassName();                                                      
2999 -            Intent intent = new Intent(                                                                           
3000 -                    Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
3001 -            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
3002 -                    Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
3003 -            startActivity(intent);                                                                                
3004 -            return true;                                                                                          
3005 -        }                                                                                                         
3006 -    }                                                                                                             
3007 -                                                                                                                  
3008 -    boolean startActivity(View v, Intent intent, Object tag) {                                                    
3009 -        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
3010 -                                                                                                                  
3011 -        try {                                                                                                     
3012 -            // Only launch using the new animation if the shortcut has not opted out (this is a                   
3013 -            // private contract between launcher and may be ignored in the future).                               
3014 -            boolean useLaunchAnimation = (v != null) &&                                                           
3015 -                    !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
3016 -            if (useLaunchAnimation) {                                                                             
3017 -                ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                              
3018 -                        v.getMeasuredWidth(), v.getMeasuredHeight());                                             
3019 -                                                                                                                  
3020 -                startActivity(intent, opts.toBundle());                                                           
3021 -            } else {                                                                                              
3022 -                startActivity(intent);                                                                            
3023 -            }                                                                                                     
3024 -            return true;                                                                                          
3025 -        } catch (SecurityException e) {                                                                           
3026 -            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3027 -            Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
3028 -                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
3029 -                    "or use the exported attribute for this activity. "                                           
3030 -                    + "tag="+ tag + " intent=" + intent, e);                                                      
3031 -        }                                                                                                         
3032 -        return false;                                                                                             
3033 -    }                                                                                                             
3034 -                                                                                                                  
3035 -    boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
3036 -        boolean success = false;                                                                                  
3037 -        try {                                                                                                     
3038 -            success = startActivity(v, intent, tag);                                                              
3039 -        } catch (ActivityNotFoundException e) {                                                                   
3040 -            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3041 -            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
3042 -        }                                                                                                         
3043 -        return success;                                                                                           
3044 -    }                                                                                                             
3045 -                                                                                                                  
3046 -    private void handleFolderClick(FolderIcon folderIcon) {                                                       
3047 +            throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
3048 +        }                                                                                                         
3049 +                                                                                                                  
3050 +        boolean success = startActivitySafely(v, intent, tag);                                                    
3051 +        mStats.recordLaunch(intent, shortcut);                                                                    
3052 +                                                                                                                  
3053 +        if (success && v instanceof BubbleTextView) {                                                             
3054 +            mWaitingForResume = (BubbleTextView) v;                                                               
3055 +            mWaitingForResume.setStayPressed(true);                                                               
3056 +        }                                                                                                         
3057 +    }                                                                                                             
3058 +                                                                                                                  
3059 +    /**                                                                                                           
3060 +     * Event handler for a folder icon click.                                                                     
3061 +     *                                                                                                            
3062 +     * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
3063 +     */                                                                                                           
3064 +    protected void onClickFolderIcon(View v) {                                                                    
3065 +        if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
3066 +        if (!(v instanceof FolderIcon)){                                                                          
3067 +            throw new IllegalArgumentException("Input must be a FolderIcon");                                     
3068 +        }                                                                                                         
3069 +                                                                                                                  
3070 +        FolderIcon folderIcon = (FolderIcon) v;                                                                   
3071          final FolderInfo info = folderIcon.getFolderInfo();                                                       
3072          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
3073                                                                                                                    
3074          // If the folder info reports that the associated folder is open, then verify that                        
3075          // it is actually opened. There have been a few instances where this gets out of sync.                    
3076          if (info.opened && openFolder == null) {                                                                  
3077              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
3078                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
3079              info.opened = false;                                                                                  
3080          }                                                                                                         
3081                                                                                                                    
3082          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
3083              // Close any open folder                                                                              
3084              closeFolder();                                                                                        
3085              // Open the requested folder                                                                          
3086              openFolder(folderIcon);                                                                               
3087          } else {                                                                                                  
3088              // Find the open folder...                                                                            
3089              int folderScreen;                                                                                     
3090              if (openFolder != null) {                                                                             
3091                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
3092                  // .. and close it                                                                                
3093                  closeFolder(openFolder);                                                                          
3094                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
3095                      // Close any folder open on the current screen                                                
3096                      closeFolder();                                                                                
3097                      // Pull the folder onto this screen                                                           
3098                      openFolder(folderIcon);                                                                       
3099                  }                                                                                                 
3100              }                                                                                                     
3101          }                                                                                                         
3102      }                                                                                                             
3103                                                                                                                    
3104      /**                                                                                                           
3105 +     * Event handler for the (Add) Widgets button that appears after a long press                                 
3106 +     * on the home screen.                                                                                        
3107 +     */                                                                                                           
3108 +    protected void onClickAddWidgetButton(View view) {                                                            
3109 +        if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
3110 +        showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                      
3111 +    }                                                                                                             
3112 +                                                                                                                  
3113 +    /**                                                                                                           
3114 +     * Event handler for the wallpaper picker button that appears after a long press                              
3115 +     * on the home screen.                                                                                        
3116 +     */                                                                                                           
3117 +    protected void onClickWallpaperPicker(View v) {                                                               
3118 +        if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
3119 +        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
3120 +        pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
3121 +        startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
3122 +    }                                                                                                             
3123 +                                                                                                                  
3124 +    /**                                                                                                           
3125 +     * Event handler for a click on the settings button that appears after a long press                           
3126 +     * on the home screen.                                                                                        
3127 +     */                                                                                                           
3128 +    protected void onClickSettingsButton(View v) {                                                                
3129 +        if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
3130 +    }                                                                                                             
3131 +                                                                                                                  
3132 +    public void onTouchDownAllAppsButton(View v) {                                                                
3133 +        // Provide the same haptic feedback that the system offers for virtual keys.                              
3134 +        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
3135 +    }                                                                                                             
3136 +                                                                                                                  
3137 +    public void performHapticFeedbackOnTouchDown(View v) {                                                        
3138 +        // Provide the same haptic feedback that the system offers for virtual keys.                              
3139 +        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
3140 +    }                                                                                                             
3141 +                                                                                                                  
3142 +    public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
3143 +        if (mHapticFeedbackTouchListener == null) {                                                               
3144 +            mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
3145 +                @Override                                                                                         
3146 +                public boolean onTouch(View v, MotionEvent event) {                                               
3147 +                    if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
3148 +                        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
3149 +                    }                                                                                             
3150 +                    return false;                                                                                 
3151 +                }                                                                                                 
3152 +            };                                                                                                    
3153 +        }                                                                                                         
3154 +        return mHapticFeedbackTouchListener;                                                                      
3155 +    }                                                                                                             
3156 +                                                                                                                  
3157 +    public void onDragStarted(View view) {}                                                                       
3158 +                                                                                                                  
3159 +    /**                                                                                                           
3160 +     * Called when the user stops interacting with the launcher.                                                  
3161 +     * This implies that the user is now on the homescreen and is not doing housekeeping.                         
3162 +     */                                                                                                           
3163 +    protected void onInteractionEnd() {}                                                                          
3164 +                                                                                                                  
3165 +    /**                                                                                                           
3166 +     * Called when the user starts interacting with the launcher.                                                 
3167 +     * The possible interactions are:                                                                             
3168 +     *  - open all apps                                                                                           
3169 +     *  - reorder an app shortcut, or a widget                                                                    
3170 +     *  - open the overview mode.                                                                                 
3171 +     * This is a good time to stop doing things that only make sense                                              
3172 +     * when the user is on the homescreen and not doing housekeeping.                                             
3173 +     */                                                                                                           
3174 +    protected void onInteractionBegin() {}                                                                        
3175 +                                                                                                                  
3176 +    void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
3177 +        String packageName = componentName.getPackageName();                                                      
3178 +        try {                                                                                                     
3179 +            LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
3180 +            UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
3181 +            launcherApps.showAppDetailsForProfile(componentName, user);                                           
3182 +        } catch (SecurityException e) {                                                                           
3183 +            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3184 +            Log.e(TAG, "Launcher does not have permission to launch settings");                                   
3185 +        } catch (ActivityNotFoundException e) {                                                                   
3186 +            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3187 +            Log.e(TAG, "Unable to launch settings");                                                              
3188 +        }                                                                                                         
3189 +    }                                                                                                             
3190 +                                                                                                                  
3191 +    // returns true if the activity was started                                                                   
3192 +    boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
3193 +            UserHandleCompat user) {                                                                              
3194 +        if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
3195 +            // System applications cannot be installed. For now, show a toast explaining that.                    
3196 +            // We may give them the option of disabling apps this way.                                            
3197 +            int messageId = R.string.uninstall_system_app_text;                                                   
3198 +            Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
3199 +            return false;                                                                                         
3200 +        } else {                                                                                                  
3201 +            String packageName = componentName.getPackageName();                                                  
3202 +            String className = componentName.getClassName();                                                      
3203 +            Intent intent = new Intent(                                                                           
3204 +                    Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
3205 +            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
3206 +                    Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
3207 +            if (user != null) {                                                                                   
3208 +                user.addToIntent(intent, Intent.EXTRA_USER);                                                      
3209 +            }                                                                                                     
3210 +            startActivity(intent);                                                                                
3211 +            return true;                                                                                          
3212 +        }                                                                                                         
3213 +    }                                                                                                             
3214 +                                                                                                                  
3215 +    boolean startActivity(View v, Intent intent, Object tag) {                                                    
3216 +        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
3217 +        try {                                                                                                     
3218 +            // Only launch using the new animation if the shortcut has not opted out (this is a                   
3219 +            // private contract between launcher and may be ignored in the future).                               
3220 +            boolean useLaunchAnimation = (v != null) &&                                                           
3221 +                    !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
3222 +            LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
3223 +            UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
3224 +                                                                                                                  
3225 +            UserHandleCompat user = null;                                                                         
3226 +            if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
3227 +                long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
3228 +                user = userManager.getUserForSerialNumber(serialNumber);                                          
3229 +            }                                                                                                     
3230 +                                                                                                                  
3231 +            Bundle optsBundle = null;                                                                             
3232 +            if (useLaunchAnimation) {                                                                             
3233 +                ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
3234 +                        ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       
3235 +                        ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
3236 +                optsBundle = opts.toBundle();                                                                     
3237 +            }                                                                                                     
3238 +                                                                                                                  
3239 +            if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
3240 +                // Could be launching some bookkeeping activity                                                   
3241 +                startActivity(intent, optsBundle);                                                                
3242 +            } else {                                                                                              
3243 +                // TODO Component can be null when shortcuts are supported for secondary user                     
3244 +                launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
3245 +                        intent.getSourceBounds(), optsBundle);                                                    
3246 +            }                                                                                                     
3247 +            return true;                                                                                          
3248 +        } catch (SecurityException e) {                                                                           
3249 +            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3250 +            Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
3251 +                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
3252 +                    "or use the exported attribute for this activity. "                                           
3253 +                    + "tag="+ tag + " intent=" + intent, e);                                                      
3254 +        }                                                                                                         
3255 +        return false;                                                                                             
3256 +    }                                                                                                             
3257 +                                                                                                                  
3258 +    boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
3259 +        boolean success = false;                                                                                  
3260 +        if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
3261 +            Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
3262 +            return false;                                                                                         
3263 +        }                                                                                                         
3264 +        try {                                                                                                     
3265 +            success = startActivity(v, intent, tag);                                                              
3266 +        } catch (ActivityNotFoundException e) {                                                                   
3267 +            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3268 +            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
3269 +        }                                                                                                         
3270 +        return success;                                                                                           
3271 +    }                                                                                                             
3272 +                                                                                                                  
3273 +    /**                                                                                                           
3274       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
3275       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
3276       */                                                                                                           
3277      private void copyFolderIconToImage(FolderIcon fi) {                                                           
3278          final int width = fi.getMeasuredWidth();                                                                  
3279          final int height = fi.getMeasuredHeight();                                                                
3280                                                                                                                    
3281          // Lazy load ImageView, Bitmap and Canvas                                                                 
3282          if (mFolderIconImageView == null) {                                                                       
3283              mFolderIconImageView = new ImageView(this);                                                           
3284          }                                                                                                         
3285          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
3286                  mFolderIconBitmap.getHeight() != height) {                                                        
3287              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
3288              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
3289          }                                                                                                         
3290                                                                                                                    
3291          DragLayer.LayoutParams lp;                                                                                
3292          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
3293              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
3294          } else {                                                                                                  
3295              lp = new DragLayer.LayoutParams(width, height);                                                       
3296          }                                                                                                         
3297                                                                                                                    
3298          // The layout from which the folder is being opened may be scaled, adjust the starting                    
3299          // view size by this scale factor.                                                                        
3300          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
3301          lp.customPosition = true;                                                                                 
3302          lp.x = mRectForFolderAnimation.left;                                                                      
3303          lp.y = mRectForFolderAnimation.top;                                                                       
3304          lp.width = (int) (scale * width);                                                                         
3305          lp.height = (int) (scale * height);                                                                       
3306                                                                                                                    
3307          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
3308          fi.draw(mFolderIconCanvas);                                                                               
3309          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3310          if (fi.getFolder() != null) {                                                                             
3311              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3312              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3313          }                                                                                                         
3314          // Just in case this image view is still in the drag layer from a previous animation,                     
3315          // we remove it and re-add it.                                                                            
3316          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3317              mDragLayer.removeView(mFolderIconImageView);                                                          
3318          }                                                                                                         
3319          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3320          if (fi.getFolder() != null) {                                                                             
3321              fi.getFolder().bringToFront();                                                                        
3322          }                                                                                                         
3323      }                                                                                                             
3324                                                                                                                    
3325      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3326          if (fi == null) return;                                                                                   
3327          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3328          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3329          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3330                                                                                                                    
3331          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3332          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3333              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3334              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3335              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3336          }                                                                                                         
3337                                                                                                                    
3338          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3339          copyFolderIconToImage(fi);                                                                                
3340          fi.setVisibility(View.INVISIBLE);                                                                         
3341                                                                                                                    
3342          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3343                  scaleX, scaleY);                                                                                  
3344 -        oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration));                           
3345 +        if (Utilities.isLmpOrAbove()) {                                                                           
3346 +            oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3347 +        }                                                                                                         
3348 +        oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3349          oa.start();                                                                                               
3350      }                                                                                                             
3351                                                                                                                    
3352      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3353          if (fi == null) return;                                                                                   
3354          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3355          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3356          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3357                                                                                                                    
3358          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3359                                                                                                                    
3360          // We remove and re-draw the FolderIcon in-case it has changed                                            
3361          mDragLayer.removeView(mFolderIconImageView);                                                              
3362          copyFolderIconToImage(fi);                                                                                
3363          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3364                  scaleX, scaleY);                                                                                  
3365 -        oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration));                           
3366 +        oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3367          oa.addListener(new AnimatorListenerAdapter() {                                                            
3368              @Override                                                                                             
3369              public void onAnimationEnd(Animator animation) {                                                      
3370                  if (cl != null) {                                                                                 
3371                      cl.clearFolderLeaveBehind();                                                                  
3372                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3373                      mDragLayer.removeView(mFolderIconImageView);                                                  
3374                      fi.setVisibility(View.VISIBLE);                                                               
3375                  }                                                                                                 
3376              }                                                                                                     
3377          });                                                                                                       
3378          oa.start();                                                                                               
3379      }                                                                                                             
3380                                                                                                                    
3381      /**                                                                                                           
3382       * Opens the user folder described by the specified tag. The opening of the folder                            
3383       * is animated relative to the specified View. If the View is null, no animation                              
3384       * is played.                                                                                                 
3385       *                                                                                                            
3386       * @param folderInfo The FolderInfo describing the folder to open.                                            
3387       */                                                                                                           
3388      public void openFolder(FolderIcon folderIcon) {                                                               
3389          Folder folder = folderIcon.getFolder();                                                                   
3390          FolderInfo info = folder.mInfo;                                                                           
3391                                                                                                                    
3392          info.opened = true;                                                                                       
3393                                                                                                                    
3394          // Just verify that the folder hasn't already been added to the DragLayer.                                
3395          // There was a one-off crash where the folder had a parent already.                                       
3396          if (folder.getParent() == null) {                                                                         
3397              mDragLayer.addView(folder);                                                                           
3398              mDragController.addDropTarget((DropTarget) folder);                                                   
3399          } else {                                                                                                  
3400              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3401                      folder.getParent() + ").");                                                                   
3402          }                                                                                                         
3403          folder.animateOpen();                                                                                     
3404          growAndFadeOutFolderIcon(folderIcon);                                                                     
3405                                                                                                                    
3406          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3407          // the workspace items                                                                                    
3408          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3409          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3410      }                                                                                                             
3411                                                                                                                    
3412      public void closeFolder() {                                                                                   
3413          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3414          if (folder != null) {                                                                                     
3415              if (folder.isEditingName()) {                                                                         
3416                  folder.dismissEditingName();                                                                      
3417              }                                                                                                     
3418              closeFolder(folder);                                                                                  
3419 -                                                                                                                  
3420 -            // Dismiss the folder cling                                                                           
3421 -            mLauncherClings.dismissFolderCling(null);                                                             
3422          }                                                                                                         
3423      }                                                                                                             
3424                                                                                                                    
3425      void closeFolder(Folder folder) {                                                                             
3426          folder.getInfo().opened = false;                                                                          
3427                                                                                                                    
3428          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3429          if (parent != null) {                                                                                     
3430              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3431              shrinkAndFadeInFolderIcon(fi);                                                                        
3432          }                                                                                                         
3433          folder.animateClosed();                                                                                   
3434                                                                                                                    
3435          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3436          // longer occludeds the workspace items                                                                   
3437          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3438      }                                                                                                             
3439                                                                                                                    
3440      public boolean onLongClick(View v) {                                                                          
3441          if (!isDraggingEnabled()) return false;                                                                   
3442          if (isWorkspaceLocked()) return false;                                                                    
3443          if (mState != State.WORKSPACE) return false;                                                              
3444                                                                                                                    
3445          if (v instanceof Workspace) {                                                                             
3446              if (!mWorkspace.isInOverviewMode()) {                                                                 
3447                  if (mWorkspace.enterOverviewMode()) {                                                             
3448                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3449                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3450                      return true;                                                                                  
3451                  } else {                                                                                          
3452                      return false;                                                                                 
3453                  }                                                                                                 
3454 -            }                                                                                                     
3455 -        }                                                                                                         
3456 -                                                                                                                  
3457 -        if (!(v instanceof CellLayout)) {                                                                         
3458 -            v = (View) v.getParent().getParent();                                                                 
3459 -        }                                                                                                         
3460 -                                                                                                                  
3461 -        resetAddInfo();                                                                                           
3462 -        CellLayout.CellInfo longClickCellInfo = (CellLayout.CellInfo) v.getTag();                                 
3463 -        // This happens when long clicking an item with the dpad/trackball                                        
3464 -        if (longClickCellInfo == null) {                                                                          
3465 -            return true;                                                                                          
3466 +            } else {                                                                                              
3467 +                return false;                                                                                     
3468 +            }                                                                                                     
3469 +        }                                                                                                         
3470 +                                                                                                                  
3471 +        CellLayout.CellInfo longClickCellInfo = null;                                                             
3472 +        View itemUnderLongClick = null;                                                                           
3473 +        if (v.getTag() instanceof ItemInfo) {                                                                     
3474 +            ItemInfo info = (ItemInfo) v.getTag();                                                                
3475 +            longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                
3476 +            itemUnderLongClick = longClickCellInfo.cell;                                                          
3477 +            resetAddInfo();                                                                                       
3478          }                                                                                                         
3479                                                                                                                    
3480          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3481          // on hotseat items.                                                                                      
3482 -        final View itemUnderLongClick = longClickCellInfo.cell;                                                   
3483          final boolean inHotseat = isHotseatLayout(v);                                                             
3484          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3485          if (allowLongPress && !mDragController.isDragging()) {                                                    
3486              if (itemUnderLongClick == null) {                                                                     
3487                  // User long pressed on empty space                                                               
3488                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3489                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3490 -                // Disabling reordering until we sort out some issues.                                            
3491                  if (mWorkspace.isInOverviewMode()) {                                                              
3492                      mWorkspace.startReordering(v);                                                                
3493                  } else {                                                                                          
3494                      mWorkspace.enterOverviewMode();                                                               
3495                  }                                                                                                 
3496              } else {                                                                                              
3497                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3498                          mHotseat.getOrderInHotseat(                                                               
3499                                  longClickCellInfo.cellX,                                                          
3500                                  longClickCellInfo.cellY));                                                        
3501                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3502                      // User long pressed on an item                                                               
3503                      mWorkspace.startDrag(longClickCellInfo);                                                      
3504                  }                                                                                                 
3505              }                                                                                                     
3506          }                                                                                                         
3507          return true;                                                                                              
3508      }                                                                                                             
3509                                                                                                                    
3510      boolean isHotseatLayout(View layout) {                                                                        
3511          return mHotseat != null && layout != null &&                                                              
3512                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3513      }                                                                                                             
3514                                                                                                                    
3515      /**                                                                                                           
3516       * Returns the CellLayout of the specified container at the specified screen.                                 
3517       */                                                                                                           
3518      CellLayout getCellLayout(long container, long screenId) {                                                     
3519          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3520              if (mHotseat != null) {                                                                               
3521                  return mHotseat.getLayout();                                                                      
3522              } else {                                                                                              
3523                  return null;                                                                                      
3524              }                                                                                                     
3525          } else {                                                                                                  
3526              return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3527          }                                                                                                         
3528      }                                                                                                             
3529                                                                                                                    
3530      public boolean isAllAppsVisible() {                                                                           
3531          return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3532 -    }                                                                                                             
3533 -                                                                                                                  
3534 -    /**                                                                                                           
3535 -     * Helper method for the cameraZoomIn/cameraZoomOut animations                                                
3536 -     * @param view The view being animated                                                                        
3537 -     * @param scaleFactor The scale factor used for the zoom                                                      
3538 -     */                                                                                                           
3539 -    private void setPivotsForZoom(View view, float scaleFactor) {                                                 
3540 -        view.setPivotX(view.getWidth() / 2.0f);                                                                   
3541 -        view.setPivotY(view.getHeight() / 2.0f);                                                                  
3542      }                                                                                                             
3543                                                                                                                    
3544      private void setWorkspaceBackground(boolean workspace) {                                                      
3545          mLauncherView.setBackground(workspace ?                                                                   
3546                  mWorkspaceBackgroundDrawable : null);                                                             
3547      }                                                                                                             
3548                                                                                                                    
3549      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3550          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3551          int curflags = getWindow().getAttributes().flags                                                          
3552                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3553          if (wpflags != curflags) {                                                                                
3554              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3555          }                                                                                                         
3556          setWorkspaceBackground(visible);                                                                          
3557      }                                                                                                             
3558                                                                                                                    
3559      private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3560          if (v instanceof LauncherTransitionable) {                                                                
3561              ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3562          }                                                                                                         
3563      }                                                                                                             
3564                                                                                                                    
3565      private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3566          if (v instanceof LauncherTransitionable) {                                                                
3567              ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3568          }                                                                                                         
3569                                                                                                                    
3570          // Update the workspace transition step as well                                                           
3571          dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3572      }                                                                                                             
3573                                                                                                                    
3574      private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3575          if (v instanceof LauncherTransitionable) {                                                                
3576              ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3577          }                                                                                                         
3578      }                                                                                                             
3579                                                                                                                    
3580      private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3581          if (v instanceof LauncherTransitionable) {                                                                
3582              ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3583          }                                                                                                         
3584                                                                                                                    
3585          // Update the workspace transition step as well                                                           
3586          dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3587      }                                                                                                             
3588                                                                                                                    
3589      /**                                                                                                           
3590       * Things to test when changing the following seven functions.                                                
3591       *   - Home from workspace                                                                                    
3592       *          - from center screen                                                                              
3593       *          - from other screens                                                                              
3594       *   - Home from all apps                                                                                     
3595       *          - from center screen                                                                              
3596       *          - from other screens                                                                              
3597       *   - Back from all apps                                                                                     
3598       *          - from center screen                                                                              
3599       *          - from other screens                                                                              
3600       *   - Launch app from workspace and quit                                                                     
3601       *          - with back                                                                                       
3602       *          - with home                                                                                       
3603       *   - Launch app from all apps and quit                                                                      
3604       *          - with back                                                                                       
3605       *          - with home                                                                                       
3606       *   - Go to a screen that's not the default, then all                                                        
3607       *     apps, and launch and app, and go back                                                                  
3608       *          - with back                                                                                       
3609       *          -with home                                                                                        
3610       *   - On workspace, long press power and go back                                                             
3611       *          - with back                                                                                       
3612       *          - with home                                                                                       
3613       *   - On all apps, long press power and go back                                                              
3614       *          - with back                                                                                       
3615       *          - with home                                                                                       
3616       *   - On workspace, power off                                                                                
3617       *   - On all apps, power off                                                                                 
3618       *   - Launch an app and turn off the screen while in that app                                                
3619       *          - Go back with home key                                                                           
3620       *          - Go back with back key  TODO: make this not go to workspace                                      
3621       *          - From all apps                                                                                   
3622       *          - From workspace                                                                                  
3623       *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3624       *          - From all apps                                                                                   
3625       *          - From the center workspace                                                                       
3626       *          - From another workspace                                                                          
3627       */                                                                                                           
3628                                                                                                                    
3629      /**                                                                                                           
3630       * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3631       * Assumes that the view to show is anchored at either the very top or very bottom                            
3632       * of the screen.                                                                                             
3633       */                                                                                                           
3634      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3635          AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3636          showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3637      }                                                                                                             
3638 +                                                                                                                  
3639      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3640                                           final AppsCustomizePagedView.ContentType contentType) {                  
3641          if (mStateAnimation != null) {                                                                            
3642              mStateAnimation.setDuration(0);                                                                       
3643              mStateAnimation.cancel();                                                                             
3644              mStateAnimation = null;                                                                               
3645          }                                                                                                         
3646 +                                                                                                                  
3647 +        boolean material = Utilities.isLmpOrAbove();                                                              
3648 +                                                                                                                  
3649          final Resources res = getResources();                                                                     
3650                                                                                                                    
3651          final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);                            
3652          final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);                        
3653 +        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3654 +        final int itemsAlphaStagger =                                                                             
3655 +                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3656 +                                                                                                                  
3657          final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                
3658          final View fromView = mWorkspace;                                                                         
3659          final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3660 -        final int startDelay =                                                                                    
3661 -                res.getInteger(R.integer.config_workspaceAppsCustomizeAnimationStagger);                          
3662 -                                                                                                                  
3663 -        setPivotsForZoom(toView, scale);                                                                          
3664 -                                                                                                                  
3665 -        // Shrink workspaces away if going to AppsCustomize from workspace                                        
3666 +                                                                                                                  
3667 +        final ArrayList<View> layerViews = new ArrayList<View>();                                                 
3668 +                                                                                                                  
3669 +        Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3670 +                Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3671          Animator workspaceAnim =                                                                                  
3672 -                mWorkspace.getChangeStateAnimation(Workspace.State.SMALL, animated);                              
3673 +                mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3674          if (!LauncherAppState.isDisableAllApps()                                                                  
3675                  || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3676              // Set the content type for the all apps/widgets space                                                
3677              mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3678          }                                                                                                         
3679                                                                                                                    
3680 -        if (animated) {                                                                                           
3681 -            toView.setScaleX(scale);                                                                              
3682 -            toView.setScaleY(scale);                                                                              
3683 -            final LauncherViewPropertyAnimator scaleAnim = new LauncherViewPropertyAnimator(toView);              
3684 -            scaleAnim.                                                                                            
3685 -                scaleX(1f).scaleY(1f).                                                                            
3686 -                setDuration(duration).                                                                            
3687 -                setInterpolator(new Workspace.ZoomOutInterpolator());                                             
3688 -                                                                                                                  
3689 -            toView.setVisibility(View.VISIBLE);                                                                   
3690 -            toView.setAlpha(0f);                                                                                  
3691 -            final ObjectAnimator alphaAnim = LauncherAnimUtils                                                    
3692 -                .ofFloat(toView, "alpha", 0f, 1f)                                                                 
3693 -                .setDuration(fadeDuration);                                                                       
3694 -            alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f));                                          
3695 -            alphaAnim.addUpdateListener(new AnimatorUpdateListener() {                                            
3696 -                @Override                                                                                         
3697 -                public void onAnimationUpdate(ValueAnimator animation) {                                          
3698 -                    if (animation == null) {                                                                      
3699 -                        throw new RuntimeException("animation is null");                                          
3700 +        // If for some reason our views aren't initialized, don't animate                                         
3701 +        boolean initialized = getAllAppsButton() != null;                                                         
3702 +                                                                                                                  
3703 +        if (animated && initialized) {                                                                            
3704 +            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3705 +            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3706 +                    toView.findViewById(R.id.apps_customize_pane_content);                                        
3707 +                                                                                                                  
3708 +            final View page = content.getPageAt(content.getCurrentPage());                                        
3709 +            final View revealView = toView.findViewById(R.id.fake_page);                                          
3710 +                                                                                                                  
3711 +            final float initialPanelAlpha = 1f;                                                                   
3712 +                                                                                                                  
3713 +            final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3714 +            if (isWidgetTray) {                                                                                   
3715 +                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3716 +            } else {                                                                                              
3717 +                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3718 +            }                                                                                                     
3719 +                                                                                                                  
3720 +            // Hide the real page background, and swap in the fake one                                            
3721 +            content.setPageBackgroundsVisible(false);                                                             
3722 +            revealView.setVisibility(View.VISIBLE);                                                               
3723 +            // We need to hide this view as the animation start will be posted.                                   
3724 +            revealView.setAlpha(0);                                                                               
3725 +                                                                                                                  
3726 +            int width = revealView.getMeasuredWidth();                                                            
3727 +            int height = revealView.getMeasuredHeight();                                                          
3728 +            float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3729 +                                                                                                                  
3730 +            revealView.setTranslationY(0);                                                                        
3731 +            revealView.setTranslationX(0);                                                                        
3732 +                                                                                                                  
3733 +            // Get the y delta between the center of the page and the center of the all apps button               
3734 +            int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3735 +                    getAllAppsButton(), null);                                                                    
3736 +                                                                                                                  
3737 +            float alpha = 0;                                                                                      
3738 +            float xDrift = 0;                                                                                     
3739 +            float yDrift = 0;                                                                                     
3740 +            if (material) {                                                                                       
3741 +                alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3742 +                yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3743 +                xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3744 +            } else {                                                                                              
3745 +                yDrift = 2 * height / 3;                                                                          
3746 +                xDrift = 0;                                                                                       
3747 +            }                                                                                                     
3748 +            final float initAlpha = alpha;                                                                        
3749 +                                                                                                                  
3750 +            revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                              
3751 +            layerViews.add(revealView);                                                                           
3752 +            PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3753 +            PropertyValuesHolder panelDriftY =                                                                    
3754 +                    PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3755 +            PropertyValuesHolder panelDriftX =                                                                    
3756 +                    PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3757 +                                                                                                                  
3758 +            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3759 +                    panelAlpha, panelDriftY, panelDriftX);                                                        
3760 +                                                                                                                  
3761 +            panelAlphaAndDrift.setDuration(revealDuration);                                                       
3762 +            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3763 +                                                                                                                  
3764 +            mStateAnimation.play(panelAlphaAndDrift);                                                             
3765 +                                                                                                                  
3766 +            if (page != null) {                                                                                   
3767 +                page.setVisibility(View.VISIBLE);                                                                 
3768 +                page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                                
3769 +                layerViews.add(page);                                                                             
3770 +                                                                                                                  
3771 +                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3772 +                page.setTranslationY(yDrift);                                                                     
3773 +                pageDrift.setDuration(revealDuration);                                                            
3774 +                pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3775 +                pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3776 +                mStateAnimation.play(pageDrift);                                                                  
3777 +                                                                                                                  
3778 +                page.setAlpha(0f);                                                                                
3779 +                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3780 +                itemsAlpha.setDuration(revealDuration);                                                           
3781 +                itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3782 +                itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3783 +                mStateAnimation.play(itemsAlpha);                                                                 
3784 +            }                                                                                                     
3785 +                                                                                                                  
3786 +            View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3787 +            pageIndicators.setAlpha(0.01f);                                                                       
3788 +            ObjectAnimator indicatorsAlpha =                                                                      
3789 +                    ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3790 +            indicatorsAlpha.setDuration(revealDuration);                                                          
3791 +            mStateAnimation.play(indicatorsAlpha);                                                                
3792 +                                                                                                                  
3793 +            if (material) {                                                                                       
3794 +                final View allApps = getAllAppsButton();                                                          
3795 +                int allAppsButtonSize = LauncherAppState.getInstance().                                           
3796 +                        getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3797 +                float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3798 +                Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3799 +                                height / 2, startRadius, revealRadius);                                           
3800 +                reveal.setDuration(revealDuration);                                                               
3801 +                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3802 +                                                                                                                  
3803 +                reveal.addListener(new AnimatorListenerAdapter() {                                                
3804 +                    public void onAnimationStart(Animator animation) {                                            
3805 +                        if (!isWidgetTray) {                                                                      
3806 +                            allApps.setVisibility(View.INVISIBLE);                                                
3807 +                        }                                                                                         
3808                      }                                                                                             
3809 -                    float t = (Float) animation.getAnimatedValue();                                               
3810 -                    dispatchOnLauncherTransitionStep(fromView, t);                                                
3811 -                    dispatchOnLauncherTransitionStep(toView, t);                                                  
3812 -                }                                                                                                 
3813 -            });                                                                                                   
3814 -                                                                                                                  
3815 -            // toView should appear right at the end of the workspace shrink                                      
3816 -            // animation                                                                                          
3817 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3818 -            mStateAnimation.play(scaleAnim).after(startDelay);                                                    
3819 -            mStateAnimation.play(alphaAnim).after(startDelay);                                                    
3820 +                    public void onAnimationEnd(Animator animation) {                                              
3821 +                        if (!isWidgetTray) {                                                                      
3822 +                            allApps.setVisibility(View.VISIBLE);                                                  
3823 +                        }                                                                                         
3824 +                    }                                                                                             
3825 +                });                                                                                               
3826 +                mStateAnimation.play(reveal);                                                                     
3827 +            }                                                                                                     
3828                                                                                                                    
3829              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3830 -                @Override                                                                                         
3831 -                public void onAnimationStart(Animator animation) {                                                
3832 -                    // Prepare the position                                                                       
3833 -                    toView.setTranslationX(0.0f);                                                                 
3834 -                    toView.setTranslationY(0.0f);                                                                 
3835 -                    toView.setVisibility(View.VISIBLE);                                                           
3836 -                    toView.bringToFront();                                                                        
3837 -                }                                                                                                 
3838                  @Override                                                                                         
3839                  public void onAnimationEnd(Animator animation) {                                                  
3840                      dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3841                      dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3842 +                                                                                                                  
3843 +                    revealView.setVisibility(View.INVISIBLE);                                                     
3844 +                    revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                          
3845 +                    if (page != null) {                                                                           
3846 +                        page.setLayerType(View.LAYER_TYPE_NONE, null);                                            
3847 +                    }                                                                                             
3848 +                    content.setPageBackgroundsVisible(true);                                                      
3849                                                                                                                    
3850                      // Hide the search bar                                                                        
3851                      if (mSearchDropTargetBar != null) {                                                           
3852                          mSearchDropTargetBar.hideSearchBar(false);                                                
3853                      }                                                                                             
3854                  }                                                                                                 
3855 +                                                                                                                  
3856              });                                                                                                   
3857                                                                                                                    
3858              if (workspaceAnim != null) {                                                                          
3859                  mStateAnimation.play(workspaceAnim);                                                              
3860              }                                                                                                     
3861                                                                                                                    
3862 -            boolean delayAnim = false;                                                                            
3863 -                                                                                                                  
3864              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3865              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3866 -                                                                                                                  
3867 -            // If any of the objects being animated haven't been measured/laid out                                
3868 -            // yet, delay the animation until we get a layout pass                                                
3869 -            if ((((LauncherTransitionable) toView).getContent().getMeasuredWidth() == 0) ||                       
3870 -                    (mWorkspace.getMeasuredWidth() == 0) ||                                                       
3871 -                    (toView.getMeasuredWidth() == 0)) {                                                           
3872 -                delayAnim = true;                                                                                 
3873 -            }                                                                                                     
3874 -                                                                                                                  
3875              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3876              final Runnable startAnimRunnable = new Runnable() {                                                   
3877                  public void run() {                                                                               
3878                      // Check that mStateAnimation hasn't changed while                                            
3879                      // we waited for a layout/draw pass                                                           
3880                      if (mStateAnimation != stateAnimation)                                                        
3881                          return;                                                                                   
3882 -                    setPivotsForZoom(toView, scale);                                                              
3883                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3884                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3885 -                    LauncherAnimUtils.startAnimationAfterNextDraw(mStateAnimation, toView);                       
3886 +                                                                                                                  
3887 +                    revealView.setAlpha(initAlpha);                                                               
3888 +                    if (Utilities.isLmpOrAbove()) {                                                               
3889 +                        for (int i = 0; i < layerViews.size(); i++) {                                             
3890 +                            View v = layerViews.get(i);                                                           
3891 +                            if (v != null) {                                                                      
3892 +                                boolean attached = true;                                                          
3893 +                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                        
3894 +                                    attached = v.isAttachedToWindow();                                            
3895 +                                }                                                                                 
3896 +                                if (attached) v.buildLayer();                                                     
3897 +                            }                                                                                     
3898 +                        }                                                                                         
3899 +                    }                                                                                             
3900 +                    mStateAnimation.start();                                                                      
3901                  }                                                                                                 
3902              };                                                                                                    
3903 -            if (delayAnim) {                                                                                      
3904 -                final ViewTreeObserver observer = toView.getViewTreeObserver();                                   
3905 -                observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {                                 
3906 -                        public void onGlobalLayout() {                                                            
3907 -                            startAnimRunnable.run();                                                              
3908 -                            toView.getViewTreeObserver().removeOnGlobalLayoutListener(this);                      
3909 -                        }                                                                                         
3910 -                    });                                                                                           
3911 -            } else {                                                                                              
3912 -                startAnimRunnable.run();                                                                          
3913 -            }                                                                                                     
3914 +            toView.bringToFront();                                                                                
3915 +            toView.setVisibility(View.VISIBLE);                                                                   
3916 +            toView.post(startAnimRunnable);                                                                       
3917          } else {                                                                                                  
3918              toView.setTranslationX(0.0f);                                                                         
3919              toView.setTranslationY(0.0f);                                                                         
3920              toView.setScaleX(1.0f);                                                                               
3921              toView.setScaleY(1.0f);                                                                               
3922              toView.setVisibility(View.VISIBLE);                                                                   
3923              toView.bringToFront();                                                                                
3924                                                                                                                    
3925              if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3926                  // Hide the search bar                                                                            
3927                  if (mSearchDropTargetBar != null) {                                                               
3928                      mSearchDropTargetBar.hideSearchBar(false);                                                    
3929                  }                                                                                                 
3930              }                                                                                                     
3931              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3932              dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3933              dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3934              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3935              dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3936              dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3937          }                                                                                                         
3938      }                                                                                                             
3939                                                                                                                    
3940      /**                                                                                                           
3941       * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3942       * This is the opposite of showAppsCustomizeHelper.                                                           
3943       * @param animated If true, the transition will be animated.                                                  
3944       */                                                                                                           
3945      private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3946              final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3947                                                                                                                    
3948          if (mStateAnimation != null) {                                                                            
3949              mStateAnimation.setDuration(0);                                                                       
3950              mStateAnimation.cancel();                                                                             
3951              mStateAnimation = null;                                                                               
3952          }                                                                                                         
3953 +                                                                                                                  
3954 +        boolean material = Utilities.isLmpOrAbove();                                                              
3955          Resources res = getResources();                                                                           
3956                                                                                                                    
3957          final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);                           
3958 -        final int fadeOutDuration =                                                                               
3959 -                res.getInteger(R.integer.config_appsCustomizeFadeOutTime);                                        
3960 +        final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);                    
3961 +        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3962 +        final int itemsAlphaStagger =                                                                             
3963 +                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3964 +                                                                                                                  
3965          final float scaleFactor = (float)                                                                         
3966                  res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);                                    
3967          final View fromView = mAppsCustomizeTabHost;                                                              
3968          final View toView = mWorkspace;                                                                           
3969          Animator workspaceAnim = null;                                                                            
3970 +        final ArrayList<View> layerViews = new ArrayList<View>();                                                 
3971 +                                                                                                                  
3972          if (toState == Workspace.State.NORMAL) {                                                                  
3973 -            int stagger = res.getInteger(R.integer.config_appsCustomizeWorkspaceAnimationStagger);                
3974              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3975 -                    toState, animated, stagger, -1);                                                              
3976 +                    toState, animated, layerViews);                                                               
3977          } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3978                  toState == Workspace.State.OVERVIEW) {                                                            
3979              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3980 -                    toState, animated);                                                                           
3981 -        }                                                                                                         
3982 -                                                                                                                  
3983 -        setPivotsForZoom(fromView, scaleFactor);                                                                  
3984 -        showHotseat(animated);                                                                                    
3985 -        if (animated) {                                                                                           
3986 -            final LauncherViewPropertyAnimator scaleAnim =                                                        
3987 -                    new LauncherViewPropertyAnimator(fromView);                                                   
3988 -            scaleAnim.                                                                                            
3989 -                scaleX(scaleFactor).scaleY(scaleFactor).                                                          
3990 -                setDuration(duration).                                                                            
3991 -                setInterpolator(new Workspace.ZoomInInterpolator());                                              
3992 -                                                                                                                  
3993 -            final ObjectAnimator alphaAnim = LauncherAnimUtils                                                    
3994 -                .ofFloat(fromView, "alpha", 1f, 0f)                                                               
3995 -                .setDuration(fadeOutDuration);                                                                    
3996 -            alphaAnim.setInterpolator(new AccelerateDecelerateInterpolator());                                    
3997 -            alphaAnim.addUpdateListener(new AnimatorUpdateListener() {                                            
3998 -                @Override                                                                                         
3999 -                public void onAnimationUpdate(ValueAnimator animation) {                                          
4000 -                    float t = 1f - (Float) animation.getAnimatedValue();                                          
4001 -                    dispatchOnLauncherTransitionStep(fromView, t);                                                
4002 -                    dispatchOnLauncherTransitionStep(toView, t);                                                  
4003 +                    toState, animated, layerViews);                                                               
4004 +        }                                                                                                         
4005 +                                                                                                                  
4006 +        // If for some reason our views aren't initialized, don't animate                                         
4007 +        boolean initialized = getAllAppsButton() != null;                                                         
4008 +                                                                                                                  
4009 +        if (animated && initialized) {                                                                            
4010 +            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
4011 +            if (workspaceAnim != null) {                                                                          
4012 +                mStateAnimation.play(workspaceAnim);                                                              
4013 +            }                                                                                                     
4014 +                                                                                                                  
4015 +            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
4016 +                    fromView.findViewById(R.id.apps_customize_pane_content);                                      
4017 +                                                                                                                  
4018 +            final View page = content.getPageAt(content.getNextPage());                                           
4019 +                                                                                                                  
4020 +            // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
4021 +            int count = content.getChildCount();                                                                  
4022 +            for (int i = 0; i < count; i++) {                                                                     
4023 +                View child = content.getChildAt(i);                                                               
4024 +                if (child != page) {                                                                              
4025 +                    child.setVisibility(View.INVISIBLE);                                                          
4026                  }                                                                                                 
4027 -            });                                                                                                   
4028 -                                                                                                                  
4029 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
4030 -                                                                                                                  
4031 -            dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
4032 -            dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
4033 -            mAppsCustomizeContent.stopScrolling();                                                                
4034 +            }                                                                                                     
4035 +            final View revealView = fromView.findViewById(R.id.fake_page);                                        
4036 +                                                                                                                  
4037 +            // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
4038 +            // don't perform all these no-op animations. In particularly, this was causing                        
4039 +            // the all-apps button to pop in and out.                                                             
4040 +            if (fromView.getVisibility() == View.VISIBLE) {                                                       
4041 +                AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
4042 +                final boolean isWidgetTray =                                                                      
4043 +                        contentType == AppsCustomizePagedView.ContentType.Widgets;                                
4044 +                                                                                                                  
4045 +                if (isWidgetTray) {                                                                               
4046 +                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
4047 +                } else {                                                                                          
4048 +                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
4049 +                }                                                                                                 
4050 +                                                                                                                  
4051 +                int width = revealView.getMeasuredWidth();                                                        
4052 +                int height = revealView.getMeasuredHeight();                                                      
4053 +                float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
4054 +                                                                                                                  
4055 +                // Hide the real page background, and swap in the fake one                                        
4056 +                revealView.setVisibility(View.VISIBLE);                                                           
4057 +                content.setPageBackgroundsVisible(false);                                                         
4058 +                                                                                                                  
4059 +                final View allAppsButton = getAllAppsButton();                                                    
4060 +                revealView.setTranslationY(0);                                                                    
4061 +                int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
4062 +                        allAppsButton, null);                                                                     
4063 +                                                                                                                  
4064 +                float xDrift = 0;                                                                                 
4065 +                float yDrift = 0;                                                                                 
4066 +                if (material) {                                                                                   
4067 +                    yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
4068 +                    xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
4069 +                } else {                                                                                          
4070 +                    yDrift = 5 * height / 4;                                                                      
4071 +                    xDrift = 0;                                                                                   
4072 +                }                                                                                                 
4073 +                                                                                                                  
4074 +                revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                          
4075 +                TimeInterpolator decelerateInterpolator = material ?                                              
4076 +                        new LogDecelerateInterpolator(100, 0) :                                                   
4077 +                        new LogDecelerateInterpolator(30, 0);                                                     
4078 +                                                                                                                  
4079 +                // The vertical motion of the apps panel should be delayed by one frame                           
4080 +                // from the conceal animation in order to give the right feel. We correpsondingly                 
4081 +                // shorten the duration so that the slide and conceal end at the same time.                       
4082 +                ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
4083 +                        0, yDrift);                                                                               
4084 +                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
4085 +                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
4086 +                panelDriftY.setInterpolator(decelerateInterpolator);                                              
4087 +                mStateAnimation.play(panelDriftY);                                                                
4088 +                                                                                                                  
4089 +                ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
4090 +                        0, xDrift);                                                                               
4091 +                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
4092 +                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
4093 +                panelDriftX.setInterpolator(decelerateInterpolator);                                              
4094 +                mStateAnimation.play(panelDriftX);                                                                
4095 +                                                                                                                  
4096 +                if (isWidgetTray || !material) {                                                                  
4097 +                    float finalAlpha = material ? 0.4f : 0f;                                                      
4098 +                    revealView.setAlpha(1f);                                                                      
4099 +                    ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
4100 +                            1f, finalAlpha);                                                                      
4101 +                    panelAlpha.setDuration(revealDuration);                                                       
4102 +                    panelAlpha.setInterpolator(material ? decelerateInterpolator :                                
4103 +                        new AccelerateInterpolator(1.5f));                                                        
4104 +                    mStateAnimation.play(panelAlpha);                                                             
4105 +                }                                                                                                 
4106 +                                                                                                                  
4107 +                if (page != null) {                                                                               
4108 +                    page.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                            
4109 +                                                                                                                  
4110 +                    ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
4111 +                            0, yDrift);                                                                           
4112 +                    page.setTranslationY(0);                                                                      
4113 +                    pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
4114 +                    pageDrift.setInterpolator(decelerateInterpolator);                                            
4115 +                    pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
4116 +                    mStateAnimation.play(pageDrift);                                                              
4117 +                                                                                                                  
4118 +                    page.setAlpha(1f);                                                                            
4119 +                    ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
4120 +                    itemsAlpha.setDuration(100);                                                                  
4121 +                    itemsAlpha.setInterpolator(decelerateInterpolator);                                           
4122 +                    mStateAnimation.play(itemsAlpha);                                                             
4123 +                }                                                                                                 
4124 +                                                                                                                  
4125 +                View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
4126 +                pageIndicators.setAlpha(1f);                                                                      
4127 +                ObjectAnimator indicatorsAlpha =                                                                  
4128 +                        LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
4129 +                indicatorsAlpha.setDuration(revealDuration);                                                      
4130 +                indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
4131 +                mStateAnimation.play(indicatorsAlpha);                                                            
4132 +                                                                                                                  
4133 +                width = revealView.getMeasuredWidth();                                                            
4134 +                                                                                                                  
4135 +                if (material) {                                                                                   
4136 +                    if (!isWidgetTray) {                                                                          
4137 +                        allAppsButton.setVisibility(View.INVISIBLE);                                              
4138 +                    }                                                                                             
4139 +                    int allAppsButtonSize = LauncherAppState.getInstance().                                       
4140 +                            getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
4141 +                    float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
4142 +                    Animator reveal =                                                                             
4143 +                            LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
4144 +                                    height / 2, revealRadius, finalRadius);                                       
4145 +                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
4146 +                    reveal.setDuration(revealDuration);                                                           
4147 +                    reveal.setStartDelay(itemsAlphaStagger);                                                      
4148 +                                                                                                                  
4149 +                    reveal.addListener(new AnimatorListenerAdapter() {                                            
4150 +                        public void onAnimationEnd(Animator animation) {                                          
4151 +                            revealView.setVisibility(View.INVISIBLE);                                             
4152 +                            if (!isWidgetTray) {                                                                  
4153 +                                allAppsButton.setVisibility(View.VISIBLE);                                        
4154 +                            }                                                                                     
4155 +                        }                                                                                         
4156 +                    });                                                                                           
4157 +                                                                                                                  
4158 +                    mStateAnimation.play(reveal);                                                                 
4159 +                }                                                                                                 
4160 +                                                                                                                  
4161 +                dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
4162 +                dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
4163 +                mAppsCustomizeContent.stopScrolling();                                                            
4164 +            }                                                                                                     
4165                                                                                                                    
4166              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
4167                  @Override                                                                                         
4168                  public void onAnimationEnd(Animator animation) {                                                  
4169                      fromView.setVisibility(View.GONE);                                                            
4170                      dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
4171                      dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
4172                      if (onCompleteRunnable != null) {                                                             
4173                          onCompleteRunnable.run();                                                                 
4174                      }                                                                                             
4175 +                                                                                                                  
4176 +                    revealView.setLayerType(View.LAYER_TYPE_NONE, null);                                          
4177 +                    if (page != null) {                                                                           
4178 +                        page.setLayerType(View.LAYER_TYPE_NONE, null);                                            
4179 +                    }                                                                                             
4180 +                    content.setPageBackgroundsVisible(true);                                                      
4181 +                    // Unhide side pages                                                                          
4182 +                    int count = content.getChildCount();                                                          
4183 +                    for (int i = 0; i < count; i++) {                                                             
4184 +                        View child = content.getChildAt(i);                                                       
4185 +                        child.setVisibility(View.VISIBLE);                                                        
4186 +                    }                                                                                             
4187 +                                                                                                                  
4188 +                    // Reset page transforms                                                                      
4189 +                    if (page != null) {                                                                           
4190 +                        page.setTranslationX(0);                                                                  
4191 +                        page.setTranslationY(0);                                                                  
4192 +                        page.setAlpha(1);                                                                         
4193 +                    }                                                                                             
4194 +                    content.setCurrentPage(content.getNextPage());                                                
4195 +                                                                                                                  
4196                      mAppsCustomizeContent.updateCurrentPageScroll();                                              
4197                  }                                                                                                 
4198              });                                                                                                   
4199                                                                                                                    
4200 -            mStateAnimation.playTogether(scaleAnim, alphaAnim);                                                   
4201 -            if (workspaceAnim != null) {                                                                          
4202 -                mStateAnimation.play(workspaceAnim);                                                              
4203 -            }                                                                                                     
4204 -            dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
4205 -            dispatchOnLauncherTransitionStart(toView, animated, true);                                            
4206 -            LauncherAnimUtils.startAnimationAfterNextDraw(mStateAnimation, toView);                               
4207 +            final AnimatorSet stateAnimation = mStateAnimation;                                                   
4208 +            final Runnable startAnimRunnable = new Runnable() {                                                   
4209 +                public void run() {                                                                               
4210 +                    // Check that mStateAnimation hasn't changed while                                            
4211 +                    // we waited for a layout/draw pass                                                           
4212 +                    if (mStateAnimation != stateAnimation)                                                        
4213 +                        return;                                                                                   
4214 +                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
4215 +                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
4216 +                                                                                                                  
4217 +                    if (Utilities.isLmpOrAbove()) {                                                               
4218 +                        for (int i = 0; i < layerViews.size(); i++) {                                             
4219 +                            View v = layerViews.get(i);                                                           
4220 +                            if (v != null) {                                                                      
4221 +                                boolean attached = true;                                                          
4222 +                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                        
4223 +                                    attached = v.isAttachedToWindow();                                            
4224 +                                }                                                                                 
4225 +                                if (attached) v.buildLayer();                                                     
4226 +                            }                                                                                     
4227 +                        }                                                                                         
4228 +                    }                                                                                             
4229 +                    mStateAnimation.start();                                                                      
4230 +                }                                                                                                 
4231 +            };                                                                                                    
4232 +            fromView.post(startAnimRunnable);                                                                     
4233          } else {                                                                                                  
4234              fromView.setVisibility(View.GONE);                                                                    
4235              dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
4236              dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
4237              dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
4238              dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
4239              dispatchOnLauncherTransitionStart(toView, animated, true);                                            
4240              dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
4241          }                                                                                                         
4242      }                                                                                                             
4243                                                                                                                    
4244      @Override                                                                                                     
4245      public void onTrimMemory(int level) {                                                                         
4246          super.onTrimMemory(level);                                                                                
4247          if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {                                                  
4248              mAppsCustomizeTabHost.onTrimMemory();                                                                 
4249          }                                                                                                         
4250      }                                                                                                             
4251                                                                                                                    
4252      protected void showWorkspace(boolean animated) {                                                              
4253          showWorkspace(animated, null);                                                                            
4254      }                                                                                                             
4255                                                                                                                    
4256      protected void showWorkspace() {                                                                              
4257          showWorkspace(true);                                                                                      
4258      }                                                                                                             
4259                                                                                                                    
4260      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
4261 -        if (mWorkspace.isInOverviewMode()) {                                                                      
4262 -            mWorkspace.exitOverviewMode(animated);                                                                
4263 -        }                                                                                                         
4264 -        if (mState != State.WORKSPACE) {                                                                          
4265 +        if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
4266              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
4267              mWorkspace.setVisibility(View.VISIBLE);                                                               
4268              hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 
4269                                                                                                                    
4270              // Show the search bar (only animate if we were showing the drop target bar in spring                 
4271              // loaded mode)                                                                                       
4272              if (mSearchDropTargetBar != null) {                                                                   
4273                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
4274              }                                                                                                     
4275                                                                                                                    
4276              // Set focus to the AppsCustomize button                                                              
4277              if (mAllAppsButton != null) {                                                                         
4278                  mAllAppsButton.requestFocus();                                                                    
4279              }                                                                                                     
4280          }                                                                                                         
4281                                                                                                                    
4282          // Change the state *after* we've called all the transition code                                          
4283          mState = State.WORKSPACE;                                                                                 
4284                                                                                                                    
4285          // Resume the auto-advance of widgets                                                                     
4286          mUserPresent = true;                                                                                      
4287          updateRunning();                                                                                          
4288                                                                                                                    
4289          // Send an accessibility event to announce the context change                                             
4290          getWindow().getDecorView()                                                                                
4291                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4292                                                                                                                    
4293          onWorkspaceShown(animated);                                                                               
4294      }                                                                                                             
4295                                                                                                                    
4296      void showOverviewMode(boolean animated) {                                                                     
4297          mWorkspace.setVisibility(View.VISIBLE);                                                                   
4298          hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
4299          mState = State.WORKSPACE;                                                                                 
4300          onWorkspaceShown(animated);                                                                               
4301      }                                                                                                             
4302                                                                                                                    
4303      public void onWorkspaceShown(boolean animated) {                                                              
4304      }                                                                                                             
4305                                                                                                                    
4306      void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
4307                       boolean resetPageToZero) {                                                                   
4308          if (mState != State.WORKSPACE) return;                                                                    
4309                                                                                                                    
4310          if (resetPageToZero) {                                                                                    
4311              mAppsCustomizeTabHost.reset();                                                                        
4312          }                                                                                                         
4313          showAppsCustomizeHelper(animated, false, contentType);                                                    
4314 -        mAppsCustomizeTabHost.requestFocus();                                                                     
4315 +        mAppsCustomizeTabHost.post(new Runnable() {                                                               
4316 +            @Override                                                                                             
4317 +            public void run() {                                                                                   
4318 +                // We post this in-case the all apps view isn't yet constructed.                                  
4319 +                mAppsCustomizeTabHost.requestFocus();                                                             
4320 +            }                                                                                                     
4321 +        });                                                                                                       
4322                                                                                                                    
4323          // Change the state *after* we've called all the transition code                                          
4324          mState = State.APPS_CUSTOMIZE;                                                                            
4325                                                                                                                    
4326          // Pause the auto-advance of widgets until we are out of AllApps                                          
4327          mUserPresent = false;                                                                                     
4328          updateRunning();                                                                                          
4329          closeFolder();                                                                                            
4330                                                                                                                    
4331          // Send an accessibility event to announce the context change                                             
4332          getWindow().getDecorView()                                                                                
4333                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4334      }                                                                                                             
4335                                                                                                                    
4336      void enterSpringLoadedDragMode() {                                                                            
4337          if (isAllAppsVisible()) {                                                                                 
4338              hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
4339              mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
4340          }                                                                                                         
4341      }                                                                                                             
4342                                                                                                                    
4343      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
4344              final Runnable onCompleteRunnable) {                                                                  
4345          if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 
4346                                                                                                                    
4347          mHandler.postDelayed(new Runnable() {                                                                     
4348              @Override                                                                                             
4349              public void run() {                                                                                   
4350                  if (successfulDrop) {                                                                             
4351                      // Before we show workspace, hide all apps again because                                      
4352                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
4353                      // clean up our state transition functions                                                    
4354                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
4355                      showWorkspace(true, onCompleteRunnable);                                                      
4356                  } else {                                                                                          
4357                      exitSpringLoadedDragMode();                                                                   
4358                  }                                                                                                 
4359              }                                                                                                     
4360          }, delay);                                                                                                
4361 -                                                                                                                  
4362      }                                                                                                             
4363                                                                                                                    
4364      void exitSpringLoadedDragMode() {                                                                             
4365          if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
4366              final boolean animated = true;                                                                        
4367              final boolean springLoaded = true;                                                                    
4368              showAppsCustomizeHelper(animated, springLoaded);                                                      
4369              mState = State.APPS_CUSTOMIZE;                                                                        
4370          }                                                                                                         
4371          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
4372      }                                                                                                             
4373                                                                                                                    
4374      void lockAllApps() {                                                                                          
4375          // TODO                                                                                                   
4376      }                                                                                                             
4377                                                                                                                    
4378      void unlockAllApps() {                                                                                        
4379          // TODO                                                                                                   
4380 -    }                                                                                                             
4381 -                                                                                                                  
4382 -    /**                                                                                                           
4383 -     * Shows the hotseat area.                                                                                    
4384 -     */                                                                                                           
4385 -    void showHotseat(boolean animated) {                                                                          
4386 -        if (!LauncherAppState.getInstance().isScreenLarge()) {                                                    
4387 -            if (animated) {                                                                                       
4388 -                if (mHotseat.getAlpha() != 1f) {                                                                  
4389 -                    int duration = 0;                                                                             
4390 -                    if (mSearchDropTargetBar != null) {                                                           
4391 -                        duration = mSearchDropTargetBar.getTransitionInDuration();                                
4392 -                    }                                                                                             
4393 -                    mHotseat.animate().alpha(1f).setDuration(duration);                                           
4394 -                }                                                                                                 
4395 -            } else {                                                                                              
4396 -                mHotseat.setAlpha(1f);                                                                            
4397 -            }                                                                                                     
4398 -        }                                                                                                         
4399      }                                                                                                             
4400                                                                                                                    
4401      /**                                                                                                           
4402       * Hides the hotseat area.                                                                                    
4403       */                                                                                                           
4404      void hideHotseat(boolean animated) {                                                                          
4405          if (!LauncherAppState.getInstance().isScreenLarge()) {                                                    
4406              if (animated) {                                                                                       
4407                  if (mHotseat.getAlpha() != 0f) {                                                                  
4408                      int duration = 0;                                                                             
4409                      if (mSearchDropTargetBar != null) {                                                           
4410                          duration = mSearchDropTargetBar.getTransitionOutDuration();                               
4411                      }                                                                                             
4412                      mHotseat.animate().alpha(0f).setDuration(duration);                                           
4413                  }                                                                                                 
4414              } else {                                                                                              
4415                  mHotseat.setAlpha(0f);                                                                            
4416              }                                                                                                     
4417          }                                                                                                         
4418      }                                                                                                             
4419                                                                                                                    
4420      /**                                                                                                           
4421       * Add an item from all apps or customize onto the given workspace screen.                                    
4422       * If layout is null, add to the current screen.                                                              
4423       */                                                                                                           
4424      void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {                                    
4425          if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {                                              
4426              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
4427          }                                                                                                         
4428      }                                                                                                             
4429                                                                                                                    
4430      /** Maps the current orientation to an index for referencing orientation correct global icons */              
4431      private int getCurrentOrientationIndexForGlobalIcons() {                                                      
4432          // default - 0, landscape - 1                                                                             
4433          switch (getResources().getConfiguration().orientation) {                                                  
4434          case Configuration.ORIENTATION_LANDSCAPE:                                                                 
4435              return 1;                                                                                             
4436          default:                                                                                                  
4437              return 0;                                                                                             
4438          }                                                                                                         
4439      }                                                                                                             
4440                                                                                                                    
4441      private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {             
4442          try {                                                                                                     
4443              PackageManager packageManager = getPackageManager();                                                  
4444              // Look for the toolbar icon specified in the activity meta-data                                      
4445              Bundle metaData = packageManager.getActivityInfo(                                                     
4446                      activityName, PackageManager.GET_META_DATA).metaData;                                         
4447              if (metaData != null) {                                                                               
4448                  int iconResId = metaData.getInt(resourceName);                                                    
4449                  if (iconResId != 0) {                                                                             
4450                      Resources res = packageManager.getResourcesForActivity(activityName);                         
4451                      return res.getDrawable(iconResId);                                                            
4452                  }                                                                                                 
4453              }                                                                                                     
4454          } catch (NameNotFoundException e) {                                                                       
4455              // This can happen if the activity defines an invalid drawable                                        
4456              Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +                    
4457                      " not found", e);                                                                             
4458          } catch (Resources.NotFoundException nfe) {                                                               
4459              // This can happen if the activity defines an invalid drawable                                        
4460              Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),                 
4461                      nfe);                                                                                         
4462          }                                                                                                         
4463          return null;                                                                                              
4464      }                                                                                                             
4465                                                                                                                    
4466      // if successful in getting icon, return it; otherwise, set button to use default drawable                    
4467      private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(                                  
4468              int buttonId, ComponentName activityName, int fallbackDrawableId,                                     
4469              String toolbarResourceName) {                                                                         
4470          Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);                  
4471          Resources r = getResources();                                                                             
4472          int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                                     
4473          int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                                    
4474                                                                                                                    
4475          TextView button = (TextView) findViewById(buttonId);                                                      
4476          // If we were unable to find the icon via the meta-data, use a generic one                                
4477          if (toolbarIcon == null) {                                                                                
4478              toolbarIcon = r.getDrawable(fallbackDrawableId);                                                      
4479              toolbarIcon.setBounds(0, 0, w, h);                                                                    
4480              if (button != null) {                                                                                 
4481                  button.setCompoundDrawables(toolbarIcon, null, null, null);                                       
4482              }                                                                                                     
4483              return null;                                                                                          
4484          } else {                                                                                                  
4485              toolbarIcon.setBounds(0, 0, w, h);                                                                    
4486              if (button != null) {                                                                                 
4487                  button.setCompoundDrawables(toolbarIcon, null, null, null);                                       
4488              }                                                                                                     
4489              return toolbarIcon.getConstantState();                                                                
4490          }                                                                                                         
4491      }                                                                                                             
4492                                                                                                                    
4493      // if successful in getting icon, return it; otherwise, set button to use default drawable                    
4494      private Drawable.ConstantState updateButtonWithIconFromExternalActivity(                                      
4495              int buttonId, ComponentName activityName, int fallbackDrawableId,                                     
4496              String toolbarResourceName) {                                                                         
4497          ImageView button = (ImageView) findViewById(buttonId);                                                    
4498          Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);                  
4499                                                                                                                    
4500          if (button != null) {                                                                                     
4501              // If we were unable to find the icon via the meta-data, use a                                        
4502              // generic one                                                                                        
4503              if (toolbarIcon == null) {                                                                            
4504                  button.setImageResource(fallbackDrawableId);                                                      
4505              } else {                                                                                              
4506                  button.setImageDrawable(toolbarIcon);                                                             
4507              }                                                                                                     
4508          }                                                                                                         
4509                                                                                                                    
4510          return toolbarIcon != null ? toolbarIcon.getConstantState() : null;                                       
4511                                                                                                                    
4512      }                                                                                                             
4513                                                                                                                    
4514      private void updateTextButtonWithDrawable(int buttonId, Drawable d) {                                         
4515          TextView button = (TextView) findViewById(buttonId);                                                      
4516          button.setCompoundDrawables(d, null, null, null);                                                         
4517      }                                                                                                             
4518                                                                                                                    
4519      private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {                               
4520          ImageView button = (ImageView) findViewById(buttonId);                                                    
4521          button.setImageDrawable(d.newDrawable(getResources()));                                                   
4522      }                                                                                                             
4523                                                                                                                    
4524      private void invalidatePressedFocusedStates(View container, View button) {                                    
4525          if (container instanceof HolographicLinearLayout) {                                                       
4526              HolographicLinearLayout layout = (HolographicLinearLayout) container;                                 
4527              layout.invalidatePressedFocusedStates();                                                              
4528          } else if (button instanceof HolographicImageView) {                                                      
4529              HolographicImageView view = (HolographicImageView) button;                                            
4530              view.invalidatePressedFocusedStates();                                                                
4531          }                                                                                                         
4532      }                                                                                                             
4533                                                                                                                    
4534      public View getQsbBar() {                                                                                     
4535          if (mQsb == null) {                                                                                       
4536              mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);                                  
4537              mSearchDropTargetBar.addView(mQsb);                                                                   
4538          }                                                                                                         
4539          return mQsb;                                                                                              
4540      }                                                                                                             
4541                                                                                                                    
4542      protected boolean updateGlobalSearchIcon() {                                                                  
4543          final View searchButtonContainer = findViewById(R.id.search_button_container);                            
4544          final ImageView searchButton = (ImageView) findViewById(R.id.search_button);                              
4545          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4546          final View voiceButton = findViewById(R.id.voice_button);                                                 
4547                                                                                                                    
4548          final SearchManager searchManager =                                                                       
4549                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                         
4550          ComponentName activityName = searchManager.getGlobalSearchActivity();                                     
4551          if (activityName != null) {                                                                               
4552              int coi = getCurrentOrientationIndexForGlobalIcons();                                                 
4553              sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                    
4554                      R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,                      
4555                      TOOLBAR_SEARCH_ICON_METADATA_NAME);                                                           
4556              if (sGlobalSearchIcon[coi] == null) {                                                                 
4557                  sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                
4558                          R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,                  
4559                          TOOLBAR_ICON_METADATA_NAME);                                                              
4560              }                                                                                                     
4561                                                                                                                    
4562              if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);                 
4563              searchButton.setVisibility(View.VISIBLE);                                                             
4564              invalidatePressedFocusedStates(searchButtonContainer, searchButton);                                  
4565              return true;                                                                                          
4566          } else {                                                                                                  
4567              // We disable both search and voice search when there is no global search provider                    
4568              if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);                    
4569              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);                      
4570              if (searchButton != null) searchButton.setVisibility(View.GONE);                                      
4571              if (voiceButton != null) voiceButton.setVisibility(View.GONE);                                        
4572              updateVoiceButtonProxyVisible(false);                                                                 
4573              return false;                                                                                         
4574          }                                                                                                         
4575      }                                                                                                             
4576                                                                                                                    
4577      protected void updateGlobalSearchIcon(Drawable.ConstantState d) {                                             
4578          final View searchButtonContainer = findViewById(R.id.search_button_container);                            
4579          final View searchButton = (ImageView) findViewById(R.id.search_button);                                   
4580          updateButtonWithDrawable(R.id.search_button, d);                                                          
4581          invalidatePressedFocusedStates(searchButtonContainer, searchButton);                                      
4582      }                                                                                                             
4583                                                                                                                    
4584      protected boolean updateVoiceSearchIcon(boolean searchVisible) {                                              
4585          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4586          final View voiceButton = findViewById(R.id.voice_button);                                                 
4587                                                                                                                    
4588          // We only show/update the voice search icon if the search icon is enabled as well                        
4589          final SearchManager searchManager =                                                                       
4590                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                         
4591          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
4592                                                                                                                    
4593          ComponentName activityName = null;                                                                        
4594          if (globalSearchActivity != null) {                                                                       
4595              // Check if the global search activity handles voice search                                           
4596              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
4597              intent.setPackage(globalSearchActivity.getPackageName());                                             
4598              activityName = intent.resolveActivity(getPackageManager());                                           
4599          }                                                                                                         
4600                                                                                                                    
4601          if (activityName == null) {                                                                               
4602              // Fallback: check if an activity other than the global search activity                               
4603              // resolves this                                                                                      
4604              Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);                                       
4605              activityName = intent.resolveActivity(getPackageManager());                                           
4606          }                                                                                                         
4607          if (searchVisible && activityName != null) {                                                              
4608              int coi = getCurrentOrientationIndexForGlobalIcons();                                                 
4609              sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                     
4610                      R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,                        
4611                      TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);                                                     
4612              if (sVoiceSearchIcon[coi] == null) {                                                                  
4613                  sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(                                 
4614                          R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,                    
4615                          TOOLBAR_ICON_METADATA_NAME);                                                              
4616              }                                                                                                     
4617              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);                   
4618              voiceButton.setVisibility(View.VISIBLE);                                                              
4619              updateVoiceButtonProxyVisible(false);                                                                 
4620              invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                                    
4621              return true;                                                                                          
4622          } else {                                                                                                  
4623              if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);                      
4624              if (voiceButton != null) voiceButton.setVisibility(View.GONE);                                        
4625              updateVoiceButtonProxyVisible(false);                                                                 
4626              return false;                                                                                         
4627          }                                                                                                         
4628      }                                                                                                             
4629                                                                                                                    
4630      protected void updateVoiceSearchIcon(Drawable.ConstantState d) {                                              
4631          final View voiceButtonContainer = findViewById(R.id.voice_button_container);                              
4632          final View voiceButton = findViewById(R.id.voice_button);                                                 
4633          updateButtonWithDrawable(R.id.voice_button, d);                                                           
4634          invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);                                        
4635      }                                                                                                             
4636                                                                                                                    
4637      public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {                             
4638          final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);                                      
4639          if (voiceButtonProxy != null) {                                                                           
4640              boolean visible = !forceDisableVoiceButtonProxy &&                                                    
4641                      mWorkspace.shouldVoiceButtonProxyBeVisible();                                                 
4642              voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);                                   
4643              voiceButtonProxy.bringToFront();                                                                      
4644          }                                                                                                         
4645      }                                                                                                             
4646                                                                                                                    
4647      /**                                                                                                           
4648       * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button proxy   
4649       * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.                               
4650       */                                                                                                           
4651      public void disableVoiceButtonProxy(boolean disabled) {                                                       
4652          updateVoiceButtonProxyVisible(disabled);                                                                  
4653      }                                                                                                             
4654 -    /**                                                                                                           
4655 -     * Sets the app market icon                                                                                   
4656 -     */                                                                                                           
4657 -    private void updateAppMarketIcon() {                                                                          
4658 -        if (!DISABLE_MARKET_BUTTON) {                                                                             
4659 -            final View marketButton = findViewById(R.id.market_button);                                           
4660 -            Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);               
4661 -            // Find the app market activity by resolving an intent.                                               
4662 -            // (If multiple app markets are installed, it will return the ResolverActivity.)                      
4663 -            ComponentName activityName = intent.resolveActivity(getPackageManager());                             
4664 -            if (activityName != null) {                                                                           
4665 -                int coi = getCurrentOrientationIndexForGlobalIcons();                                             
4666 -                mAppMarketIntent = intent;                                                                        
4667 -                sAppMarketIcon[coi] = updateTextButtonWithIconFromExternalActivity(                               
4668 -                        R.id.market_button, activityName, R.drawable.ic_launcher_market_holo,                     
4669 -                        TOOLBAR_ICON_METADATA_NAME);                                                              
4670 -                marketButton.setVisibility(View.VISIBLE);                                                         
4671 -            } else {                                                                                              
4672 -                // We should hide and disable the view so that we don't try and restore the visibility            
4673 -                // of it when we swap between drag & normal states from IconDropTarget subclasses.                
4674 -                marketButton.setVisibility(View.GONE);                                                            
4675 -                marketButton.setEnabled(false);                                                                   
4676 -            }                                                                                                     
4677 -        }                                                                                                         
4678 -    }                                                                                                             
4679 -                                                                                                                  
4680 -    private void updateAppMarketIcon(Drawable.ConstantState d) {                                                  
4681 -        if (!DISABLE_MARKET_BUTTON) {                                                                             
4682 -            // Ensure that the new drawable we are creating has the approprate toolbar icon bounds                
4683 -            Resources r = getResources();                                                                         
4684 -            Drawable marketIconDrawable = d.newDrawable(r);                                                       
4685 -            int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);                                 
4686 -            int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);                                
4687 -            marketIconDrawable.setBounds(0, 0, w, h);                                                             
4688 -                                                                                                                  
4689 -            updateTextButtonWithDrawable(R.id.market_button, marketIconDrawable);                                 
4690 -        }                                                                                                         
4691 -    }                                                                                                             
4692                                                                                                                    
4693      @Override                                                                                                     
4694      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4695          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4696          final List<CharSequence> text = event.getText();                                                          
4697          text.clear();                                                                                             
4698          // Populate event with a fake title based on the current state.                                           
4699          if (mState == State.APPS_CUSTOMIZE) {                                                                     
4700 -            text.add(mAppsCustomizeTabHost.getCurrentTabView().getContentDescription());                          
4701 +            text.add(mAppsCustomizeTabHost.getContentTag());                                                      
4702          } else {                                                                                                  
4703              text.add(getString(R.string.all_apps_home_button_label));                                             
4704          }                                                                                                         
4705          return result;                                                                                            
4706      }                                                                                                             
4707                                                                                                                    
4708      /**                                                                                                           
4709       * Receives notifications when system dialogs are to be closed.                                               
4710       */                                                                                                           
4711      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4712          @Override                                                                                                 
4713          public void onReceive(Context context, Intent intent) {                                                   
4714              closeSystemDialogs();                                                                                 
4715          }                                                                                                         
4716      }                                                                                                             
4717                                                                                                                    
4718      /**                                                                                                           
4719       * Receives notifications whenever the appwidgets are reset.                                                  
4720       */                                                                                                           
4721      private class AppWidgetResetObserver extends ContentObserver {                                                
4722          public AppWidgetResetObserver() {                                                                         
4723              super(new Handler());                                                                                 
4724          }                                                                                                         
4725                                                                                                                    
4726          @Override                                                                                                 
4727          public void onChange(boolean selfChange) {                                                                
4728              onAppWidgetReset();                                                                                   
4729          }                                                                                                         
4730      }                                                                                                             
4731                                                                                                                    
4732      /**                                                                                                           
4733       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4734       * in onResume.                                                                                               
4735       *                                                                                                            
4736       * This needs to be called from incoming places where resources might have been loaded                        
4737       * while we are paused.  That is becaues the Configuration might be wrong                                     
4738       * when we're not running, and if it comes back to what it was when we                                        
4739       * were paused, we are not restarted.                                                                         
4740       *                                                                                                            
4741       * Implementation of the method from LauncherModel.Callbacks.                                                 
4742       *                                                                                                            
4743       * @return true if we are currently paused.  The caller might be able to                                      
4744       * skip some work in that case since we will come back again.                                                 
4745       */                                                                                                           
4746      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4747          if (mPaused) {                                                                                            
4748              Log.i(TAG, "Deferring update until onResume");                                                        
4749              if (deletePreviousRunnables) {                                                                        
4750                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4751                  }                                                                                                 
4752              }                                                                                                     
4753              mBindOnResumeCallbacks.add(run);                                                                      
4754              return true;                                                                                          
4755          } else {                                                                                                  
4756              return false;                                                                                         
4757          }                                                                                                         
4758      }                                                                                                             
4759                                                                                                                    
4760      private boolean waitUntilResume(Runnable run) {                                                               
4761          return waitUntilResume(run, false);                                                                       
4762      }                                                                                                             
4763                                                                                                                    
4764      public void addOnResumeCallback(Runnable run) {                                                               
4765          mOnResumeCallbacks.add(run);                                                                              
4766      }                                                                                                             
4767                                                                                                                    
4768      /**                                                                                                           
4769       * If the activity is currently paused, signal that we need to re-run the loader                              
4770       * in onResume.                                                                                               
4771       *                                                                                                            
4772       * This needs to be called from incoming places where resources might have been loaded                        
4773       * while we are paused.  That is becaues the Configuration might be wrong                                     
4774       * when we're not running, and if it comes back to what it was when we                                        
4775       * were paused, we are not restarted.                                                                         
4776       *                                                                                                            
4777       * Implementation of the method from LauncherModel.Callbacks.                                                 
4778       *                                                                                                            
4779       * @return true if we are currently paused.  The caller might be able to                                      
4780       * skip some work in that case since we will come back again.                                                 
4781       */                                                                                                           
4782      public boolean setLoadOnResume() {                                                                            
4783          if (mPaused) {                                                                                            
4784              Log.i(TAG, "setLoadOnResume");                                                                        
4785              mOnResumeNeedsLoad = true;                                                                            
4786              return true;                                                                                          
4787          } else {                                                                                                  
4788              return false;                                                                                         
4789          }                                                                                                         
4790      }                                                                                                             
4791                                                                                                                    
4792      /**                                                                                                           
4793       * Implementation of the method from LauncherModel.Callbacks.                                                 
4794       */                                                                                                           
4795      public int getCurrentWorkspaceScreen() {                                                                      
4796          if (mWorkspace != null) {                                                                                 
4797              return mWorkspace.getCurrentPage();                                                                   
4798          } else {                                                                                                  
4799              return SCREEN_COUNT / 2;                                                                              
4800          }                                                                                                         
4801      }                                                                                                             
4802                                                                                                                    
4803      /**                                                                                                           
4804       * Refreshes the shortcuts shown on the workspace.                                                            
4805       *                                                                                                            
4806       * Implementation of the method from LauncherModel.Callbacks.                                                 
4807       */                                                                                                           
4808      public void startBinding() {                                                                                  
4809 +        setWorkspaceLoading(true);                                                                                
4810 +                                                                                                                  
4811          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4812          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4813          // from scratch again                                                                                     
4814          mBindOnResumeCallbacks.clear();                                                                           
4815                                                                                                                    
4816          // Clear the workspace because it's going to be rebound                                                   
4817          mWorkspace.clearDropTargets();                                                                            
4818          mWorkspace.removeAllWorkspaceScreens();                                                                   
4819                                                                                                                    
4820          mWidgetsToAdvance.clear();                                                                                
4821          if (mHotseat != null) {                                                                                   
4822              mHotseat.resetLayout();                                                                               
4823          }                                                                                                         
4824      }                                                                                                             
4825                                                                                                                    
4826      @Override                                                                                                     
4827      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4828          bindAddScreens(orderedScreenIds);                                                                         
4829                                                                                                                    
4830          // If there are no screens, we need to have an empty screen                                               
4831          if (orderedScreenIds.size() == 0) {                                                                       
4832              mWorkspace.addExtraEmptyScreen();                                                                     
4833          }                                                                                                         
4834                                                                                                                    
4835          // Create the custom content page (this call updates mDefaultScreen which calls                           
4836          // setCurrentPage() so ensure that all pages are added before calling this).                              
4837          if (hasCustomContentToLeft()) {                                                                           
4838              mWorkspace.createCustomContentContainer();                                                            
4839              populateCustomContentContainer();                                                                     
4840          }                                                                                                         
4841      }                                                                                                             
4842                                                                                                                    
4843      @Override                                                                                                     
4844      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4845          // Log to disk                                                                                            
4846          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4847          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4848                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4849          int count = orderedScreenIds.size();                                                                      
4850          for (int i = 0; i < count; i++) {                                                                         
4851              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4852          }                                                                                                         
4853      }                                                                                                             
4854                                                                                                                    
4855      private boolean shouldShowWeightWatcher() {                                                                   
4856          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4857          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4858          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4859                                                                                                                    
4860          return show;                                                                                              
4861      }                                                                                                             
4862                                                                                                                    
4863      private void toggleShowWeightWatcher() {                                                                      
4864          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4865          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4866          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4867                                                                                                                    
4868          show = !show;                                                                                             
4869                                                                                                                    
4870          SharedPreferences.Editor editor = sp.edit();                                                              
4871          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4872          editor.commit();                                                                                          
4873                                                                                                                    
4874          if (mWeightWatcher != null) {                                                                             
4875              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4876          }                                                                                                         
4877      }                                                                                                             
4878                                                                                                                    
4879      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4880                                final ArrayList<ItemInfo> addNotAnimated,                                           
4881                                final ArrayList<ItemInfo> addAnimated,                                              
4882                                final ArrayList<AppInfo> addedApps) {                                               
4883          Runnable r = new Runnable() {                                                                             
4884              public void run() {                                                                                   
4885                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4886              }                                                                                                     
4887          };                                                                                                        
4888          if (waitUntilResume(r)) {                                                                                 
4889              return;                                                                                               
4890          }                                                                                                         
4891                                                                                                                    
4892          // Add the new screens                                                                                    
4893 -        bindAddScreens(newScreens);                                                                               
4894 +        if (newScreens != null) {                                                                                 
4895 +            bindAddScreens(newScreens);                                                                           
4896 +        }                                                                                                         
4897                                                                                                                    
4898          // We add the items without animation on non-visible pages, and with                                      
4899          // animations on the new page (which we will try and snap to).                                            
4900 -        if (!addNotAnimated.isEmpty()) {                                                                          
4901 +        if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4902              bindItems(addNotAnimated, 0,                                                                          
4903                      addNotAnimated.size(), false);                                                                
4904          }                                                                                                         
4905 -        if (!addAnimated.isEmpty()) {                                                                             
4906 +        if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4907              bindItems(addAnimated, 0,                                                                             
4908                      addAnimated.size(), true);                                                                    
4909          }                                                                                                         
4910                                                                                                                    
4911          // Remove the extra empty screen                                                                          
4912 -        mWorkspace.removeExtraEmptyScreen(false, null);                                                           
4913 +        mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4914                                                                                                                    
4915          if (!LauncherAppState.isDisableAllApps() &&                                                               
4916                  addedApps != null && mAppsCustomizeContent != null) {                                             
4917              mAppsCustomizeContent.addApps(addedApps);                                                             
4918          }                                                                                                         
4919      }                                                                                                             
4920                                                                                                                    
4921      /**                                                                                                           
4922       * Bind the items start-end from the list.                                                                    
4923       *                                                                                                            
4924       * Implementation of the method from LauncherModel.Callbacks.                                                 
4925       */                                                                                                           
4926      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4927                            final boolean forceAnimateIcons) {                                                      
4928          Runnable r = new Runnable() {                                                                             
4929              public void run() {                                                                                   
4930                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4931              }                                                                                                     
4932          };                                                                                                        
4933          if (waitUntilResume(r)) {                                                                                 
4934              return;                                                                                               
4935          }                                                                                                         
4936                                                                                                                    
4937          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4938          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4939          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4940          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4941          Workspace workspace = mWorkspace;                                                                         
4942          long newShortcutsScreenId = -1;                                                                           
4943          for (int i = start; i < end; i++) {                                                                       
4944              final ItemInfo item = shortcuts.get(i);                                                               
4945                                                                                                                    
4946              // Short circuit if we are loading dock items for a configuration which has no dock                   
4947              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4948                      mHotseat == null) {                                                                           
4949                  continue;                                                                                         
4950              }                                                                                                     
4951                                                                                                                    
4952              switch (item.itemType) {                                                                              
4953                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4954                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4955                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4956                      View shortcut = createShortcut(info);                                                         
4957                                                                                                                    
4958                      /*                                                                                            
4959                       * TODO: FIX collision case                                                                   
4960                       */                                                                                           
4961                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4962                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4963                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4964 -                            throw new RuntimeException("OCCUPIED");                                               
4965 +                            View v = cl.getChildAt(item.cellX, item.cellY);                                       
4966 +                            Object tag = v.getTag();                                                              
4967 +                            String desc = "Collision while binding workspace item: " + item                       
4968 +                                    + ". Collides with " + tag;                                                   
4969 +                            if (LauncherAppState.isDogfoodBuild()) {                                              
4970 +                                throw (new RuntimeException(desc));                                               
4971 +                            } else {                                                                              
4972 +                                Log.d(TAG, desc);                                                                 
4973 +                            }                                                                                     
4974                          }                                                                                         
4975                      }                                                                                             
4976                                                                                                                    
4977                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4978                              item.cellY, 1, 1);                                                                    
4979                      if (animateIcons) {                                                                           
4980                          // Animate all the applications up now                                                    
4981                          shortcut.setAlpha(0f);                                                                    
4982                          shortcut.setScaleX(0f);                                                                   
4983                          shortcut.setScaleY(0f);                                                                   
4984                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4985                          newShortcutsScreenId = item.screenId;                                                     
4986                      }                                                                                             
4987                      break;                                                                                        
4988                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4989                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4990                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4991                              (FolderInfo) item, mIconCache);                                                       
4992                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4993                              item.cellY, 1, 1);                                                                    
4994                      break;                                                                                        
4995                  default:                                                                                          
4996                      throw new RuntimeException("Invalid Item Type");                                              
4997              }                                                                                                     
4998          }                                                                                                         
4999                                                                                                                    
5000          if (animateIcons) {                                                                                       
5001              // Animate to the correct page                                                                        
5002              if (newShortcutsScreenId > -1) {                                                                      
5003                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
5004                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
5005                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
5006                      public void run() {                                                                           
5007                          anim.playTogether(bounceAnims);                                                           
5008                          anim.start();                                                                             
5009                      }                                                                                             
5010                  };                                                                                                
5011                  if (newShortcutsScreenId != currentScreenId) {                                                    
5012                      // We post the animation slightly delayed to prevent slowdowns                                
5013                      // when we are loading right after we return to launcher.                                     
5014                      mWorkspace.postDelayed(new Runnable() {                                                       
5015                          public void run() {                                                                       
5016                              if (mWorkspace != null) {                                                             
5017                                  mWorkspace.snapToPage(newScreenIndex);                                            
5018                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
5019                                          NEW_APPS_ANIMATION_DELAY);                                                
5020                              }                                                                                     
5021                          }                                                                                         
5022                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
5023                  } else {                                                                                          
5024                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
5025                  }                                                                                                 
5026              }                                                                                                     
5027          }                                                                                                         
5028          workspace.requestLayout();                                                                                
5029      }                                                                                                             
5030                                                                                                                    
5031      /**                                                                                                           
5032       * Implementation of the method from LauncherModel.Callbacks.                                                 
5033       */                                                                                                           
5034      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
5035          Runnable r = new Runnable() {                                                                             
5036              public void run() {                                                                                   
5037                  bindFolders(folders);                                                                             
5038              }                                                                                                     
5039          };                                                                                                        
5040          if (waitUntilResume(r)) {                                                                                 
5041              return;                                                                                               
5042          }                                                                                                         
5043          sFolders.clear();                                                                                         
5044          sFolders.putAll(folders);                                                                                 
5045      }                                                                                                             
5046                                                                                                                    
5047      /**                                                                                                           
5048       * Add the views for a widget to the workspace.                                                               
5049       *                                                                                                            
5050       * Implementation of the method from LauncherModel.Callbacks.                                                 
5051       */                                                                                                           
5052      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
5053          Runnable r = new Runnable() {                                                                             
5054              public void run() {                                                                                   
5055                  bindAppWidget(item);                                                                              
5056              }                                                                                                     
5057          };                                                                                                        
5058          if (waitUntilResume(r)) {                                                                                 
5059              return;                                                                                               
5060          }                                                                                                         
5061                                                                                                                    
5062          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
5063          if (DEBUG_WIDGETS) {                                                                                      
5064              Log.d(TAG, "bindAppWidget: " + item);                                                                 
5065          }                                                                                                         
5066          final Workspace workspace = mWorkspace;                                                                   
5067                                                                                                                    
5068 -        final int appWidgetId = item.appWidgetId;                                                                 
5069 -        final AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);              
5070 -        if (DEBUG_WIDGETS) {                                                                                      
5071 -            Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidgetInfo.provider🔵
5072 -        }                                                                                                         
5073 -                                                                                                                  
5074 -        item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                              
5075 +        AppWidgetProviderInfo appWidgetInfo;                                                                      
5076 +        if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&                        
5077 +                ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                          
5078 +                                                                                                                  
5079 +            appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);               
5080 +            if (appWidgetInfo == null) {                                                                          
5081 +                if (DEBUG_WIDGETS) {                                                                              
5082 +                    Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
5083 +                            + " belongs to component " + item.providerName                                        
5084 +                            + ", as the povider is null");                                                        
5085 +                }                                                                                                 
5086 +                LauncherModel.deleteItemFromDatabase(this, item);                                                 
5087 +                return;                                                                                           
5088 +            }                                                                                                     
5089 +            // Note: This assumes that the id remap broadcast is received before this step.                       
5090 +            // If that is not the case, the id remap will be ignored and user may see the                         
5091 +            // click to setup view.                                                                               
5092 +            PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);               
5093 +            pendingInfo.spanX = item.spanX;                                                                       
5094 +            pendingInfo.spanY = item.spanY;                                                                       
5095 +            pendingInfo.minSpanX = item.minSpanX;                                                                 
5096 +            pendingInfo.minSpanY = item.minSpanY;                                                                 
5097 +            Bundle options =                                                                                      
5098 +                    AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
5099 +                                                                                                                  
5100 +            int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
5101 +            boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
5102 +                    newWidgetId, appWidgetInfo, options);                                                         
5103 +                                                                                                                  
5104 +            // TODO consider showing a permission dialog when the widget is clicked.                              
5105 +            if (!success) {                                                                                       
5106 +                mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
5107 +                if (DEBUG_WIDGETS) {                                                                              
5108 +                    Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
5109 +                            + " belongs to component " + item.providerName                                        
5110 +                            + ", as the launcher is unable to bing a new widget id");                             
5111 +                }                                                                                                 
5112 +                LauncherModel.deleteItemFromDatabase(this, item);                                                 
5113 +                return;                                                                                           
5114 +            }                                                                                                     
5115 +                                                                                                                  
5116 +            item.appWidgetId = newWidgetId;                                                                       
5117 +                                                                                                                  
5118 +            // If the widget has a configure activity, it is still needs to set it up, otherwise                  
5119 +            // the widget is ready to go.                                                                         
5120 +            item.restoreStatus = (appWidgetInfo.configure == null)                                                
5121 +                    ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
5122 +                    : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
5123 +                                                                                                                  
5124 +            LauncherModel.updateItemInDatabase(this, item);                                                       
5125 +        }                                                                                                         
5126 +                                                                                                                  
5127 +        if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {                                      
5128 +            final int appWidgetId = item.appWidgetId;                                                             
5129 +            appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);                                      
5130 +            if (DEBUG_WIDGETS) {                                                                                  
5131 +                Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component " + appWidgetInfo.prov🔵
5132 +            }                                                                                                     
5133 +                                                                                                                  
5134 +            item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
5135 +        } else {                                                                                                  
5136 +            appWidgetInfo = null;                                                                                 
5137 +            PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);                             
5138 +            view.updateIcon(mIconCache);                                                                          
5139 +            item.hostView = view;                                                                                 
5140 +            item.hostView.updateAppWidget(null);                                                                  
5141 +            item.hostView.setOnClickListener(this);                                                               
5142 +        }                                                                                                         
5143                                                                                                                    
5144          item.hostView.setTag(item);                                                                               
5145          item.onBindAppWidget(this);                                                                               
5146                                                                                                                    
5147          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
5148                  item.cellY, item.spanX, item.spanY, false);                                                       
5149          addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                             
5150                                                                                                                    
5151          workspace.requestLayout();                                                                                
5152                                                                                                                    
5153          if (DEBUG_WIDGETS) {                                                                                      
5154              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
5155                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
5156          }                                                                                                         
5157 +    }                                                                                                             
5158 +                                                                                                                  
5159 +    /**                                                                                                           
5160 +     * Restores a pending widget.                                                                                 
5161 +     *                                                                                                            
5162 +     * @param appWidgetId The app widget id                                                                       
5163 +     * @param cellInfo The position on screen where to create the widget.                                         
5164 +     */                                                                                                           
5165 +    private void completeRestoreAppWidget(final int appWidgetId) {                                                
5166 +        LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
5167 +        if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
5168 +            Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
5169 +            return;                                                                                               
5170 +        }                                                                                                         
5171 +                                                                                                                  
5172 +        LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
5173 +        info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
5174 +                                                                                                                  
5175 +        mWorkspace.reinflateWidgetsIfNecessary();                                                                 
5176 +        LauncherModel.updateItemInDatabase(this, info);                                                           
5177      }                                                                                                             
5178                                                                                                                    
5179      public void onPageBoundSynchronously(int page) {                                                              
5180          mSynchronouslyBoundPages.add(page);                                                                       
5181      }                                                                                                             
5182                                                                                                                    
5183      /**                                                                                                           
5184       * Callback saying that there aren't any more items to bind.                                                  
5185       *                                                                                                            
5186       * Implementation of the method from LauncherModel.Callbacks.                                                 
5187       */                                                                                                           
5188      public void finishBindingItems(final boolean upgradePath) {                                                   
5189          Runnable r = new Runnable() {                                                                             
5190              public void run() {                                                                                   
5191                  finishBindingItems(upgradePath);                                                                  
5192              }                                                                                                     
5193          };                                                                                                        
5194          if (waitUntilResume(r)) {                                                                                 
5195              return;                                                                                               
5196          }                                                                                                         
5197          if (mSavedState != null) {                                                                                
5198              if (!mWorkspace.hasFocus()) {                                                                         
5199                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
5200              }                                                                                                     
5201              mSavedState = null;                                                                                   
5202          }                                                                                                         
5203                                                                                                                    
5204          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
5205                                                                                                                    
5206 +        setWorkspaceLoading(false);                                                                               
5207 +        sendLoadingCompleteBroadcastIfNecessary();                                                                
5208 +                                                                                                                  
5209          // If we received the result of any pending adds while the loader was running (e.g. the                   
5210          // widget configuration forced an orientation change), process them now.                                  
5211 -        for (int i = 0; i < sPendingAddList.size(); i++) {                                                        
5212 -            completeAdd(sPendingAddList.get(i));                                                                  
5213 -        }                                                                                                         
5214 -        sPendingAddList.clear();                                                                                  
5215 -                                                                                                                  
5216 -        // Update the market app icon as necessary (the other icons will be managed in response to                
5217 -        // package changes in bindSearchablesChanged()                                                            
5218 -        if (!DISABLE_MARKET_BUTTON) {                                                                             
5219 -            updateAppMarketIcon();                                                                                
5220 -        }                                                                                                         
5221 -                                                                                                                  
5222 -        mWorkspaceLoading = false;                                                                                
5223 +        if (sPendingAddItem != null) {                                                                            
5224 +            final long screenId = completeAdd(sPendingAddItem);                                                   
5225 +                                                                                                                  
5226 +            // TODO: this moves the user to the page where the pending item was added. Ideally,                   
5227 +            // the screen would be guaranteed to exist after bind, and the page would be set through              
5228 +            // the workspace restore process.                                                                     
5229 +            mWorkspace.post(new Runnable() {                                                                      
5230 +                @Override                                                                                         
5231 +                public void run() {                                                                               
5232 +                    mWorkspace.snapToScreenId(screenId);                                                          
5233 +                }                                                                                                 
5234 +            });                                                                                                   
5235 +            sPendingAddItem = null;                                                                               
5236 +        }                                                                                                         
5237 +                                                                                                                  
5238          if (upgradePath) {                                                                                        
5239              mWorkspace.getUniqueComponents(true, null);                                                           
5240              mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
5241 +        }                                                                                                         
5242 +        PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
5243 +        mModel.recheckRestoredItems(this);                                                                        
5244 +    }                                                                                                             
5245 +                                                                                                                  
5246 +    private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
5247 +        if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
5248 +            String permission =                                                                                   
5249 +                    getResources().getString(R.string.receive_first_load_broadcast_permission);                   
5250 +            Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
5251 +            sendBroadcast(intent, permission);                                                                    
5252 +            SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
5253 +            editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
5254 +            editor.apply();                                                                                       
5255          }                                                                                                         
5256      }                                                                                                             
5257                                                                                                                    
5258      public boolean isAllAppsButtonRank(int rank) {                                                                
5259          if (mHotseat != null) {                                                                                   
5260              return mHotseat.isAllAppsButtonRank(rank);                                                            
5261          }                                                                                                         
5262          return false;                                                                                             
5263      }                                                                                                             
5264                                                                                                                    
5265      private boolean canRunNewAppsAnimation() {                                                                    
5266          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
5267          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
5268      }                                                                                                             
5269                                                                                                                    
5270      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
5271          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
5272                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
5273                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
5274                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
5275          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
5276          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
5277          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
5278          return bounceAnim;                                                                                        
5279      }                                                                                                             
5280                                                                                                                    
5281      public boolean useVerticalBarLayout() {                                                                       
5282          return LauncherAppState.getInstance().getDynamicGrid().                                                   
5283                  getDeviceProfile().isVerticalBarLayout();                                                         
5284      }                                                                                                             
5285                                                                                                                    
5286      protected Rect getSearchBarBounds() {                                                                         
5287          return LauncherAppState.getInstance().getDynamicGrid().                                                   
5288                  getDeviceProfile().getSearchBarBounds();                                                          
5289      }                                                                                                             
5290                                                                                                                    
5291      @Override                                                                                                     
5292      public void bindSearchablesChanged() {                                                                        
5293          boolean searchVisible = updateGlobalSearchIcon();                                                         
5294          boolean voiceVisible = updateVoiceSearchIcon(searchVisible);                                              
5295          if (mSearchDropTargetBar != null) {                                                                       
5296              mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);                            
5297          }                                                                                                         
5298      }                                                                                                             
5299                                                                                                                    
5300      /**                                                                                                           
5301       * Add the icons for all apps.                                                                                
5302       *                                                                                                            
5303       * Implementation of the method from LauncherModel.Callbacks.                                                 
5304       */                                                                                                           
5305      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
5306          if (LauncherAppState.isDisableAllApps()) {                                                                
5307              if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
5308                  if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
5309                      getHotseat().addAllAppsFolder(mIconCache, apps,                                               
5310                              mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
5311                  }                                                                                                 
5312                  mIntentsOnWorkspaceFromUpgradePath = null;                                                        
5313              }                                                                                                     
5314              if (mAppsCustomizeContent != null) {                                                                  
5315                  mAppsCustomizeContent.onPackagesUpdated(                                                          
5316                          LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
5317              }                                                                                                     
5318          } else {                                                                                                  
5319              if (mAppsCustomizeContent != null) {                                                                  
5320                  mAppsCustomizeContent.setApps(apps);                                                              
5321                  mAppsCustomizeContent.onPackagesUpdated(                                                          
5322                          LauncherModel.getSortedWidgetsAndShortcuts(this));                                        
5323              }                                                                                                     
5324          }                                                                                                         
5325      }                                                                                                             
5326                                                                                                                    
5327      /**                                                                                                           
5328       * A package was updated.                                                                                     
5329       *                                                                                                            
5330       * Implementation of the method from LauncherModel.Callbacks.                                                 
5331       */                                                                                                           
5332      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
5333          Runnable r = new Runnable() {                                                                             
5334              public void run() {                                                                                   
5335                  bindAppsUpdated(apps);                                                                            
5336              }                                                                                                     
5337          };                                                                                                        
5338          if (waitUntilResume(r)) {                                                                                 
5339              return;                                                                                               
5340          }                                                                                                         
5341                                                                                                                    
5342          if (mWorkspace != null) {                                                                                 
5343 -            mWorkspace.updateShortcuts(apps);                                                                     
5344 +            mWorkspace.updateShortcutsAndWidgets(apps);                                                           
5345          }                                                                                                         
5346                                                                                                                    
5347          if (!LauncherAppState.isDisableAllApps() &&                                                               
5348                  mAppsCustomizeContent != null) {                                                                  
5349              mAppsCustomizeContent.updateApps(apps);                                                               
5350 +        }                                                                                                         
5351 +    }                                                                                                             
5352 +                                                                                                                  
5353 +    /**                                                                                                           
5354 +     * Packages were restored                                                                                     
5355 +     */                                                                                                           
5356 +    public void bindAppsRestored(final ArrayList<AppInfo> apps) {                                                 
5357 +        Runnable r = new Runnable() {                                                                             
5358 +            public void run() {                                                                                   
5359 +                bindAppsRestored(apps);                                                                           
5360 +            }                                                                                                     
5361 +        };                                                                                                        
5362 +        if (waitUntilResume(r)) {                                                                                 
5363 +            return;                                                                                               
5364 +        }                                                                                                         
5365 +                                                                                                                  
5366 +        if (mWorkspace != null) {                                                                                 
5367 +            mWorkspace.updateShortcutsAndWidgets(apps);                                                           
5368 +        }                                                                                                         
5369 +    }                                                                                                             
5370 +                                                                                                                  
5371 +    /**                                                                                                           
5372 +     * Update the state of a package, typically related to install state.                                         
5373 +     *                                                                                                            
5374 +     * Implementation of the method from LauncherModel.Callbacks.                                                 
5375 +     */                                                                                                           
5376 +    @Override                                                                                                     
5377 +    public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
5378 +        if (mWorkspace != null) {                                                                                 
5379 +            mWorkspace.updatePackageState(installInfo);                                                           
5380 +        }                                                                                                         
5381 +    }                                                                                                             
5382 +                                                                                                                  
5383 +    /**                                                                                                           
5384 +     * Update the label and icon of all the icons in a package                                                    
5385 +     *                                                                                                            
5386 +     * Implementation of the method from LauncherModel.Callbacks.                                                 
5387 +     */                                                                                                           
5388 +    @Override                                                                                                     
5389 +    public void updatePackageBadge(String packageName) {                                                          
5390 +        if (mWorkspace != null) {                                                                                 
5391 +            mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
5392          }                                                                                                         
5393      }                                                                                                             
5394                                                                                                                    
5395      /**                                                                                                           
5396       * A package was uninstalled.  We take both the super set of packageNames                                     
5397       * in addition to specific applications to remove, the reason being that                                      
5398       * this can be called when a package is updated as well.  In that scenario,                                   
5399       * we only remove specific components from the workspace, where as                                            
5400       * package-removal should clear all items by package name.                                                    
5401       *                                                                                                            
5402       * Implementation of the method from LauncherModel.Callbacks.                                                 
5403       */                                                                                                           
5404      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
5405 -                                      final ArrayList<AppInfo> appInfos) {                                        
5406 +            final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {                                     
5407          Runnable r = new Runnable() {                                                                             
5408              public void run() {                                                                                   
5409 -                bindComponentsRemoved(packageNames, appInfos);                                                    
5410 +                bindComponentsRemoved(packageNames, appInfos, user);                                              
5411              }                                                                                                     
5412          };                                                                                                        
5413          if (waitUntilResume(r)) {                                                                                 
5414              return;                                                                                               
5415          }                                                                                                         
5416                                                                                                                    
5417          if (!packageNames.isEmpty()) {                                                                            
5418 -            mWorkspace.removeItemsByPackageName(packageNames);                                                    
5419 +            mWorkspace.removeItemsByPackageName(packageNames, user);                                              
5420          }                                                                                                         
5421          if (!appInfos.isEmpty()) {                                                                                
5422 -            mWorkspace.removeItemsByApplicationInfo(appInfos);                                                    
5423 +            mWorkspace.removeItemsByApplicationInfo(appInfos, user);                                              
5424          }                                                                                                         
5425                                                                                                                    
5426          // Notify the drag controller                                                                             
5427          mDragController.onAppsRemoved(packageNames, appInfos);                                                    
5428                                                                                                                    
5429          // Update AllApps                                                                                         
5430          if (!LauncherAppState.isDisableAllApps() &&                                                               
5431                  mAppsCustomizeContent != null) {                                                                  
5432              mAppsCustomizeContent.removeApps(appInfos);                                                           
5433          }                                                                                                         
5434      }                                                                                                             
5435                                                                                                                    
5436      /**                                                                                                           
5437       * A number of packages were updated.                                                                         
5438       */                                                                                                           
5439      private ArrayList<Object> mWidgetsAndShortcuts;                                                               
5440      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
5441              public void run() {                                                                                   
5442                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
5443                  mWidgetsAndShortcuts = null;                                                                      
5444              }                                                                                                     
5445          };                                                                                                        
5446      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
5447          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
5448              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
5449              return;                                                                                               
5450          }                                                                                                         
5451                                                                                                                    
5452          // Update the widgets pane                                                                                
5453          if (mAppsCustomizeContent != null) {                                                                      
5454              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
5455          }                                                                                                         
5456      }                                                                                                             
5457                                                                                                                    
5458      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
5459          final Display d = getWindowManager().getDefaultDisplay();                                                 
5460          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
5461          switch (d.getRotation()) {                                                                                
5462          case Surface.ROTATION_0:                                                                                  
5463          case Surface.ROTATION_180:                                                                                
5464              // We are currently in the same basic orientation as the natural orientation                          
5465              naturalOri = configOri;                                                                               
5466              break;                                                                                                
5467          case Surface.ROTATION_90:                                                                                 
5468          case Surface.ROTATION_270:                                                                                
5469              // We are currently in the other basic orientation to the natural orientation                         
5470              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
5471                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
5472              break;                                                                                                
5473          }                                                                                                         
5474                                                                                                                    
5475          int[] oriMap = {                                                                                          
5476                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
5477                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
5478                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
5479                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
5480          };                                                                                                        
5481          // Since the map starts at portrait, we need to offset if this device's natural orientation               
5482          // is landscape.                                                                                          
5483          int indexOffset = 0;                                                                                      
5484          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
5485              indexOffset = 1;                                                                                      
5486          }                                                                                                         
5487          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
5488      }                                                                                                             
5489                                                                                                                    
5490      public boolean isRotationEnabled() {                                                                          
5491          boolean enableRotation = sForceEnableRotation ||                                                          
5492                  getResources().getBoolean(R.bool.allow_rotation);                                                 
5493          return enableRotation;                                                                                    
5494      }                                                                                                             
5495      public void lockScreenOrientation() {                                                                         
5496          if (isRotationEnabled()) {                                                                                
5497              setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                             
5498                      .getConfiguration().orientation));                                                            
5499          }                                                                                                         
5500      }                                                                                                             
5501      public void unlockScreenOrientation(boolean immediate) {                                                      
5502          if (isRotationEnabled()) {                                                                                
5503              if (immediate) {                                                                                      
5504                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
5505              } else {                                                                                              
5506                  mHandler.postDelayed(new Runnable() {                                                             
5507                      public void run() {                                                                           
5508                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
5509                      }                                                                                             
5510                  }, mRestoreScreenOrientationDelay);                                                               
5511              }                                                                                                     
5512          }                                                                                                         
5513      }                                                                                                             
5514                                                                                                                    
5515      /**                                                                                                           
5516       * Called when the SearchBar hint should be changed.                                                          
5517       *                                                                                                            
5518       * @param hint the hint to be displayed in the search bar.                                                    
5519       */                                                                                                           
5520      protected void onSearchBarHintChanged(String hint) {                                                          
5521 -        mLauncherClings.updateSearchBarHint(hint);                                                                
5522 +                                                                                                                  
5523      }                                                                                                             
5524                                                                                                                    
5525      protected boolean isLauncherPreinstalled() {                                                                  
5526          PackageManager pm = getPackageManager();                                                                  
5527          try {                                                                                                     
5528              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
5529              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
5530                  return true;                                                                                      
5531              } else {                                                                                              
5532                  return false;                                                                                     
5533              }                                                                                                     
5534          } catch (NameNotFoundException e) {                                                                       
5535              e.printStackTrace();                                                                                  
5536              return false;                                                                                         
5537          }                                                                                                         
5538      }                                                                                                             
5539                                                                                                                    
5540 +    /**                                                                                                           
5541 +     * This method indicates whether or not we should suggest default wallpaper dimensions                        
5542 +     * when our wallpaper cropper was not yet used to set a wallpaper.                                            
5543 +     */                                                                                                           
5544 +    protected boolean overrideWallpaperDimensions() {                                                             
5545 +        return true;                                                                                              
5546 +    }                                                                                                             
5547 +                                                                                                                  
5548 +    protected boolean shouldClingFocusHotseatApp() {                                                              
5549 +        return false;                                                                                             
5550 +    }                                                                                                             
5551      protected String getFirstRunClingSearchBarHint() {                                                            
5552          return "";                                                                                                
5553      }                                                                                                             
5554      protected String getFirstRunCustomContentHint() {                                                             
5555          return "";                                                                                                
5556      }                                                                                                             
5557      protected int getFirstRunFocusedHotseatAppDrawableId() {                                                      
5558          return -1;                                                                                                
5559      }                                                                                                             
5560      protected ComponentName getFirstRunFocusedHotseatAppComponentName() {                                         
5561          return null;                                                                                              
5562      }                                                                                                             
5563      protected int getFirstRunFocusedHotseatAppRank() {                                                            
5564          return -1;                                                                                                
5565      }                                                                                                             
5566      protected String getFirstRunFocusedHotseatAppBubbleTitle() {                                                  
5567          return "";                                                                                                
5568      }                                                                                                             
5569      protected String getFirstRunFocusedHotseatAppBubbleDescription() {                                            
5570          return "";                                                                                                
5571      }                                                                                                             
5572                                                                                                                    
5573 -    public void dismissFirstRunCling(View v) {                                                                    
5574 -        mLauncherClings.dismissFirstRunCling(v);                                                                  
5575 -    }                                                                                                             
5576 -    public void dismissMigrationClingCopyApps(View v) {                                                           
5577 -        mLauncherClings.dismissMigrationClingCopyApps(v);                                                         
5578 -    }                                                                                                             
5579 -    public void dismissMigrationClingUseDefault(View v) {                                                         
5580 -        mLauncherClings.dismissMigrationClingUseDefault(v);                                                       
5581 -    }                                                                                                             
5582 -    public void dismissMigrationWorkspaceCling(View v) {                                                          
5583 -        mLauncherClings.dismissMigrationWorkspaceCling(v);                                                        
5584 -    }                                                                                                             
5585 -    public void dismissWorkspaceCling(View v) {                                                                   
5586 -        mLauncherClings.dismissWorkspaceCling(v);                                                                 
5587 -    }                                                                                                             
5588 -    public void dismissFolderCling(View v) {                                                                      
5589 -        mLauncherClings.dismissFolderCling(v);                                                                    
5590 +    /**                                                                                                           
5591 +     * To be overridden by subclasses to indicate that there is an activity to launch                             
5592 +     * before showing the standard launcher experience.                                                           
5593 +     */                                                                                                           
5594 +    protected boolean hasFirstRunActivity() {                                                                     
5595 +        return false;                                                                                             
5596 +    }                                                                                                             
5597 +                                                                                                                  
5598 +    /**                                                                                                           
5599 +     * To be overridden by subclasses to launch any first run activity                                            
5600 +     */                                                                                                           
5601 +    protected Intent getFirstRunActivity() {                                                                      
5602 +        return null;                                                                                              
5603      }                                                                                                             
5604                                                                                                                    
5605      private boolean shouldRunFirstRunActivity() {                                                                 
5606          return !ActivityManager.isRunningInTestHarness() &&                                                       
5607                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
5608      }                                                                                                             
5609                                                                                                                    
5610 -    public void showFirstRunActivity() {                                                                          
5611 +    protected boolean hasRunFirstRunActivity() {                                                                  
5612 +        return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
5613 +    }                                                                                                             
5614 +                                                                                                                  
5615 +    public boolean showFirstRunActivity() {                                                                       
5616          if (shouldRunFirstRunActivity() &&                                                                        
5617                  hasFirstRunActivity()) {                                                                          
5618              Intent firstRunIntent = getFirstRunActivity();                                                        
5619              if (firstRunIntent != null) {                                                                         
5620                  startActivity(firstRunIntent);                                                                    
5621                  markFirstRunActivityShown();                                                                      
5622 -            }                                                                                                     
5623 -        }                                                                                                         
5624 +                return true;                                                                                      
5625 +            }                                                                                                     
5626 +        }                                                                                                         
5627 +        return false;                                                                                             
5628      }                                                                                                             
5629                                                                                                                    
5630      private void markFirstRunActivityShown() {                                                                    
5631          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5632          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
5633          editor.apply();                                                                                           
5634 +    }                                                                                                             
5635 +                                                                                                                  
5636 +    /**                                                                                                           
5637 +     * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
5638 +     * screen that must be displayed and dismissed.                                                               
5639 +     */                                                                                                           
5640 +    protected boolean hasDismissableIntroScreen() {                                                               
5641 +        return false;                                                                                             
5642 +    }                                                                                                             
5643 +                                                                                                                  
5644 +    /**                                                                                                           
5645 +     * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
5646 +     */                                                                                                           
5647 +    protected View getIntroScreen() {                                                                             
5648 +        return null;                                                                                              
5649 +    }                                                                                                             
5650 +                                                                                                                  
5651 +    /**                                                                                                           
5652 +     * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
5653 +     * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
5654 +     */                                                                                                           
5655 +    private boolean shouldShowIntroScreen() {                                                                     
5656 +        return hasDismissableIntroScreen() &&                                                                     
5657 +                !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
5658 +    }                                                                                                             
5659 +                                                                                                                  
5660 +    protected void showIntroScreen() {                                                                            
5661 +        View introScreen = getIntroScreen();                                                                      
5662 +        changeWallpaperVisiblity(false);                                                                          
5663 +        if (introScreen != null) {                                                                                
5664 +            mDragLayer.showOverlayView(introScreen);                                                              
5665 +        }                                                                                                         
5666 +    }                                                                                                             
5667 +                                                                                                                  
5668 +    public void dismissIntroScreen() {                                                                            
5669 +        markIntroScreenDismissed();                                                                               
5670 +        if (showFirstRunActivity()) {                                                                             
5671 +            // We delay hiding the intro view until the first run activity is showing. This                       
5672 +            // avoids a blip.                                                                                     
5673 +            mWorkspace.postDelayed(new Runnable() {                                                               
5674 +                @Override                                                                                         
5675 +                public void run() {                                                                               
5676 +                    mDragLayer.dismissOverlayView();                                                              
5677 +                    showFirstRunClings();                                                                         
5678 +                }                                                                                                 
5679 +            }, ACTIVITY_START_DELAY);                                                                             
5680 +        } else {                                                                                                  
5681 +            mDragLayer.dismissOverlayView();                                                                      
5682 +            showFirstRunClings();                                                                                 
5683 +        }                                                                                                         
5684 +        changeWallpaperVisiblity(true);                                                                           
5685 +    }                                                                                                             
5686 +                                                                                                                  
5687 +    private void markIntroScreenDismissed() {                                                                     
5688 +        SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5689 +        editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5690 +        editor.apply();                                                                                           
5691 +    }                                                                                                             
5692 +                                                                                                                  
5693 +    private void showFirstRunClings() {                                                                           
5694 +        // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5695 +        // on the device, then we always show the first run cling experience (or if there is no                   
5696 +        // launcher2). Otherwise, we prompt the user upon started for migration                                   
5697 +        LauncherClings launcherClings = new LauncherClings(this);                                                 
5698 +        if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5699 +            if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5700 +                launcherClings.showMigrationCling();                                                              
5701 +            } else {                                                                                              
5702 +                launcherClings.showLongPressCling(true);                                                          
5703 +            }                                                                                                     
5704 +        }                                                                                                         
5705      }                                                                                                             
5706                                                                                                                    
5707      void showWorkspaceSearchAndHotseat() {                                                                        
5708          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5709          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5710          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5711          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5712      }                                                                                                             
5713                                                                                                                    
5714      void hideWorkspaceSearchAndHotseat() {                                                                        
5715          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5716          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5717          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5718          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5719      }                                                                                                             
5720                                                                                                                    
5721 -                                                                                                                  
5722      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5723 -        ResolveInfo ri = getPackageManager().resolveActivity(appLaunchIntent, 0);                                 
5724 -        if (ri == null) {                                                                                         
5725 +        // Called from search suggestion, not supported in other profiles.                                        
5726 +        final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5727 +        LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5728 +        LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5729 +                myUser);                                                                                          
5730 +        if (activityInfo == null) {                                                                               
5731              return null;                                                                                          
5732          }                                                                                                         
5733 -        return new AppInfo(getPackageManager(), ri, mIconCache, null);                                            
5734 +        return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         
5735      }                                                                                                             
5736                                                                                                                    
5737      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5738              Bitmap icon) {                                                                                        
5739 -        return new ShortcutInfo(shortcutIntent, caption, icon);                                                   
5740 +        // Called from search suggestion, not supported in other profiles.                                        
5741 +        return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5742 +                UserHandleCompat.myUserHandle());                                                                 
5743 +    }                                                                                                             
5744 +                                                                                                                  
5745 +    public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5746 +            Bitmap icon, UserHandleCompat user) {                                                                 
5747 +        UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5748 +        CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5749 +        return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5750 +    }                                                                                                             
5751 +                                                                                                                  
5752 +    protected void moveWorkspaceToDefaultScreen() {                                                               
5753 +        mWorkspace.moveToDefaultScreen(false);                                                                    
5754      }                                                                                                             
5755                                                                                                                    
5756      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5757          dragView.setTag(dragInfo);                                                                                
5758 -        mWorkspace.onDragStartedWithItem(dragView);                                                               
5759 -        mWorkspace.beginDragShared(dragView, source);                                                             
5760 +        mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5761 +        mWorkspace.beginExternalDragShared(dragView, source);                                                     
5762 +    }                                                                                                             
5763 +                                                                                                                  
5764 +    @Override                                                                                                     
5765 +    public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5766      }                                                                                                             
5767                                                                                                                    
5768      /**                                                                                                           
5769       * Prints out out state for debugging.                                                                        
5770       */                                                                                                           
5771      public void dumpState() {                                                                                     
5772          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5773          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5774          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5775          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5776          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5777          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5778          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5779          mModel.dumpState();                                                                                       
5780                                                                                                                    
5781          if (mAppsCustomizeContent != null) {                                                                      
5782              mAppsCustomizeContent.dumpState();                                                                    
5783          }                                                                                                         
5784          Log.d(TAG, "END launcher3 dump state");                                                                   
5785      }                                                                                                             
5786                                                                                                                    
5787      @Override                                                                                                     
5788      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5789          super.dump(prefix, fd, writer, args);                                                                     
5790          synchronized (sDumpLogs) {                                                                                
5791              writer.println(" ");                                                                                  
5792              writer.println("Debug logs: ");                                                                       
5793              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5794                  writer.println("  " + sDumpLogs.get(i));                                                          
5795              }                                                                                                     
5796          }                                                                                                         
5797      }                                                                                                             
5798                                                                                                                    
5799      public static void dumpDebugLogsToConsole() {                                                                 
5800          if (DEBUG_DUMP_LOG) {                                                                                     
5801              synchronized (sDumpLogs) {                                                                            
5802                  Log.d(TAG, "");                                                                                   
5803                  Log.d(TAG, "*********************");                                                              
5804                  Log.d(TAG, "Launcher debug logs: ");                                                              
5805                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5806                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5807                  }                                                                                                 
5808                  Log.d(TAG, "*********************");                                                              
5809                  Log.d(TAG, "");                                                                                   
5810              }                                                                                                     
5811          }                                                                                                         
5812      }                                                                                                             
5813                                                                                                                    
5814      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5815          addDumpLog(tag, log, null, debugLog);                                                                     
5816      }                                                                                                             
5817                                                                                                                    
5818      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5819          if (debugLog) {                                                                                           
5820              if (e != null) {                                                                                      
5821                  Log.d(tag, log, e);                                                                               
5822              } else {                                                                                              
5823                  Log.d(tag, log);                                                                                  
5824              }                                                                                                     
5825          }                                                                                                         
5826          if (DEBUG_DUMP_LOG) {                                                                                     
5827              sDateStamp.setTime(System.currentTimeMillis());                                                       
5828              synchronized (sDumpLogs) {                                                                            
5829                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5830                      + (e == null ? "" : (", Exception: " + e)));                                                  
5831              }                                                                                                     
5832          }                                                                                                         
5833      }                                                                                                             
5834                                                                                                                    
5835      public void dumpLogsToLocalData() {                                                                           
5836          if (DEBUG_DUMP_LOG) {                                                                                     
5837              new AsyncTask<Void, Void, Void>() {                                                                   
5838                  public Void doInBackground(Void ... args) {                                                       
5839                      boolean success = false;                                                                      
5840                      sDateStamp.setTime(sRunStart);                                                                
5841                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5842                              + sDateStamp.getDay() + "_"                                                           
5843                              + sDateStamp.getHours() + "-"                                                         
5844                              + sDateStamp.getMinutes() + "_"                                                       
5845                              + sDateStamp.getSeconds() + ".txt";                                                   
5846                                                                                                                    
5847                      FileOutputStream fos = null;                                                                  
5848                      File outFile = null;                                                                          
5849                      try {                                                                                         
5850                          outFile = new File(getFilesDir(), FILENAME);                                              
5851                          outFile.createNewFile();                                                                  
5852                          fos = new FileOutputStream(outFile);                                                      
5853                      } catch (Exception e) {                                                                       
5854                          e.printStackTrace();                                                                      
5855                      }                                                                                             
5856                      if (fos != null) {                                                                            
5857                          PrintWriter writer = new PrintWriter(fos);                                                
5858                                                                                                                    
5859                          writer.println(" ");                                                                      
5860                          writer.println("Debug logs: ");                                                           
5861                          synchronized (sDumpLogs) {                                                                
5862                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5863                                  writer.println("  " + sDumpLogs.get(i));                                          
5864                              }                                                                                     
5865                          }                                                                                         
5866                          writer.close();                                                                           
5867                      }                                                                                             
5868                      try {                                                                                         
5869                          if (fos != null) {                                                                        
5870                              fos.close();                                                                          
5871                              success = true;                                                                       
5872                          }                                                                                         
5873                      } catch (IOException e) {                                                                     
5874                          e.printStackTrace();                                                                      
5875                      }                                                                                             
5876                      return null;                                                                                  
5877                  }                                                                                                 
5878              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5879          }                                                                                                         
5880      }                                                                                                             
5881  }                                                                                                                 
5882                                                                                                                    
5883  interface LauncherTransitionable {                                                                                
5884      View getContent();                                                                                            
5885      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5886      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5887      void onLauncherTransitionStep(Launcher l, float t);                                                           
5888      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5889  }                                                                                                                 
5890                                                                                                                    
5891  interface DebugIntents {                                                                                          
5892      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5893      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5894  }